From f30d5115226a4a8a805fa59c56c60a52888ee240 Mon Sep 17 00:00:00 2001 From: Juan Olveira Date: Thu, 25 Dec 2025 11:05:13 -0300 Subject: [PATCH] Refactor serialization logic across processors to use a unified `try_serialize` function - Introduced a new `try_serialize` function in `serialize.rs` to handle serialization and validation for various account types. - Updated processors in the `exchange`, `link`, `location`, `multicastgroup`, and `user` modules to replace direct account writing with the new `try_serialize` function. - Ensured that all relevant structs implement the `Validate` trait to enforce validation before serialization. - Removed redundant helper functions and streamlined the code for better maintainability and readability. - Refactor account type handling and serialization across multiple modules - Removed the AccountTypeInfo trait implementation from Device, Exchange, Link, Location, MulticastGroup, User, and other related structs. - Replaced size calculations with borsh::object_length for more accurate serialization size checks. - Updated tests to reflect changes in size validation using borsh::object_length. - Consolidated account creation and writing logic into a new serializer module for better code organization. - Added comprehensive instruction implementation guidelines to ensure consistency and security in new instruction development. - Introduced a new foundation address file for better address management. - Refactor import statements for improved readability and consistency - changelog: add instruction guidelines and enforce best practices for onchain programs style: format imports and remove unnecessary blank line in initialize.rs refactor: update test command and enhance error handling for foundation allowlist fix: remove unnecessary whitespace in validation logic for GlobalState refactor: simplify assertions for writable accounts in initialize_global_state --- CHANGELOG.md | 4 + .../INSTRUCTION_GUIDELINES.md | 145 +++++++++++++ .../doublezero-serviceability/src/accounts.rs | 83 -------- ...oundation.rs => _doublezero_foundation.rs} | 0 .../src/addresses/mod.rs | 1 - .../src/entrypoint.rs | 4 +- .../doublezero-serviceability/src/error.rs | 5 + .../src/globalstate.rs | 169 --------------- .../doublezero-serviceability/src/helper.rs | 198 +----------------- .../doublezero-serviceability/src/lib.rs | 10 +- .../src/processors/accesspass/check_status.rs | 21 +- .../src/processors/accesspass/close.rs | 14 +- .../src/processors/accesspass/set.rs | 46 ++-- .../src/processors/allowlist/device/add.rs | 39 ++-- .../src/processors/allowlist/device/remove.rs | 38 ++-- .../processors/allowlist/foundation/add.rs | 39 ++-- .../processors/allowlist/foundation/remove.rs | 39 ++-- .../src/processors/allowlist/user/add.rs | 39 ++-- .../src/processors/allowlist/user/remove.rs | 39 ++-- .../src/processors/contributor/create.rs | 30 ++- .../src/processors/contributor/delete.rs | 13 +- .../src/processors/contributor/resume.rs | 22 +- .../src/processors/contributor/suspend.rs | 21 +- .../src/processors/contributor/update.rs | 18 +- .../src/processors/device/activate.rs | 15 +- .../src/processors/device/closeaccount.rs | 25 +-- .../src/processors/device/create.rs | 41 ++-- .../src/processors/device/delete.rs | 16 +- .../processors/device/interface/activate.rs | 14 +- .../src/processors/device/interface/create.rs | 10 +- .../src/processors/device/interface/delete.rs | 15 +- .../src/processors/device/interface/reject.rs | 14 +- .../src/processors/device/interface/remove.rs | 11 +- .../src/processors/device/interface/unlink.rs | 14 +- .../src/processors/device/interface/update.rs | 13 +- .../src/processors/device/reject.rs | 16 +- .../src/processors/device/resume.rs | 19 +- .../src/processors/device/suspend.rs | 19 +- .../src/processors/device/update.rs | 31 ++- .../src/processors/exchange/create.rs | 45 ++-- .../src/processors/exchange/delete.rs | 16 +- .../src/processors/exchange/resume.rs | 20 +- .../src/processors/exchange/setdevice.rs | 18 +- .../src/processors/exchange/suspend.rs | 15 +- .../src/processors/exchange/update.rs | 31 ++- .../src/processors/globalconfig/set.rs | 19 +- .../src/processors/globalstate/initialize.rs | 104 +++++---- .../src/processors/globalstate/setairdrop.rs | 17 +- .../processors/globalstate/setauthority.rs | 20 +- .../src/processors/globalstate/setversion.rs | 18 +- .../src/processors/link/accept.rs | 9 +- .../src/processors/link/activate.rs | 25 +-- .../src/processors/link/closeaccount.rs | 23 +- .../src/processors/link/create.rs | 43 ++-- .../src/processors/link/delete.rs | 11 +- .../src/processors/link/reject.rs | 10 +- .../src/processors/link/resume.rs | 9 +- .../src/processors/link/suspend.rs | 9 +- .../src/processors/link/update.rs | 9 +- .../src/processors/location/create.rs | 24 ++- .../src/processors/location/delete.rs | 9 +- .../src/processors/location/resume.rs | 13 +- .../src/processors/location/suspend.rs | 13 +- .../src/processors/location/update.rs | 10 +- .../src/processors/migrate.rs | 12 +- .../src/processors/multicastgroup/activate.rs | 14 +- .../multicastgroup/allowlist/publisher/add.rs | 30 +-- .../allowlist/publisher/remove.rs | 16 +- .../allowlist/subscriber/add.rs | 31 ++- .../allowlist/subscriber/remove.rs | 16 +- .../processors/multicastgroup/closeaccount.rs | 10 +- .../src/processors/multicastgroup/create.rs | 24 ++- .../src/processors/multicastgroup/delete.rs | 15 +- .../processors/multicastgroup/reactivate.rs | 17 +- .../src/processors/multicastgroup/reject.rs | 12 +- .../processors/multicastgroup/subscribe.rs | 9 +- .../src/processors/multicastgroup/suspend.rs | 15 +- .../src/processors/multicastgroup/update.rs | 12 +- .../src/processors/resource/allocate.rs | 8 +- .../src/processors/resource/create.rs | 4 +- .../src/processors/resource/deallocate.rs | 5 +- .../src/processors/user/activate.rs | 19 +- .../src/processors/user/ban.rs | 10 +- .../src/processors/user/check_access_pass.rs | 19 +- .../src/processors/user/closeaccount.rs | 11 +- .../src/processors/user/create.rs | 33 ++- .../src/processors/user/create_subscribe.rs | 35 ++-- .../src/processors/user/delete.rs | 20 +- .../src/processors/user/reject.rs | 11 +- .../src/processors/user/requestban.rs | 11 +- .../src/processors/user/resume.rs | 8 +- .../src/processors/user/suspend.rs | 10 +- .../src/processors/user/update.rs | 14 +- .../src/serializer.rs | 102 +++++++++ .../src/state/accesspass.rs | 47 ++--- .../src/state/contributor.rs | 32 +-- .../src/state/device.rs | 61 ++---- .../src/state/exchange.rs | 36 +--- .../src/state/globalconfig.rs | 11 +- .../src/state/globalstate.rs | 34 ++- .../src/state/link.rs | 52 +---- .../src/state/location.rs | 43 +--- .../src/state/multicastgroup.rs | 32 +-- .../src/state/programconfig.rs | 42 +--- .../src/state/user.rs | 54 +---- .../tests/accounts_test.rs | 19 +- .../tests/initialize_global_state_test.rs | 19 +- .../tests/user_migration.rs | 12 +- .../src/state/device_latency_samples.rs | 6 +- .../src/state/internet_latency_samples.rs | 6 +- .../sdk/rs/src/commands/globalstate/init.rs | 4 +- 111 files changed, 1303 insertions(+), 1610 deletions(-) create mode 100644 smartcontract/programs/doublezero-serviceability/INSTRUCTION_GUIDELINES.md delete mode 100644 smartcontract/programs/doublezero-serviceability/src/accounts.rs rename smartcontract/programs/doublezero-serviceability/src/addresses/{doublezero_foundation.rs => _doublezero_foundation.rs} (100%) delete mode 100644 smartcontract/programs/doublezero-serviceability/src/globalstate.rs create mode 100644 smartcontract/programs/doublezero-serviceability/src/serializer.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d963e37e0..fff3f8ea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ All notable changes to this project will be documented in this file. - Allow contributor owner to update ops manager key - Add new arguments on create interface cli command - Add ResourceExtension to track IP/ID allocations. Foundation instructions added to create/allocate/deallocate. + - Added the **INSTRUCTION_GUIDELINES** document defining the standard for instruction creation. + - Enforce best practices for instruction implementation across onchain programs + - Add missing system program account owner checks in multiple instructions + - Refactor codebase for improved maintainability and future development - Internet Latency Telemetry - Fixed a bug that prevented unresponsive ripeatlas probes from being replaced - Fixed a bug that caused ripeatlas samples to be dropped when they were delayed to the next collection cycle diff --git a/smartcontract/programs/doublezero-serviceability/INSTRUCTION_GUIDELINES.md b/smartcontract/programs/doublezero-serviceability/INSTRUCTION_GUIDELINES.md new file mode 100644 index 000000000..5d5a81a7b --- /dev/null +++ b/smartcontract/programs/doublezero-serviceability/INSTRUCTION_GUIDELINES.md @@ -0,0 +1,145 @@ +# Instruction Implementation Guidelines + +This document describes the required steps and best practices for implementing a new instruction in this Solana program. All developers must follow these guidelines to ensure correctness, security, and maintainability. + +--- + +## 1. Account Parsing and Validation + +- Parse all accounts in the order expected by the instruction. +- For each account, check: + - **Ownership:** Ensure the account is owned by the expected program (usually `program_id`). + - **Signer:** Verify that required accounts (e.g., payer) are signers. + - **Writable:** Ensure accounts that will be mutated are marked as writable. + - **System Program:** If the system program is required, check its address matches `solana_program::system_program::id()`. + - **PDA Validation:** If the instruction involves a PDA, derive the expected PDA and bump seed, and check both against the provided account and arguments. + +**Example:** +```rust +let mgroup_account = next_account_info(accounts_iter)?; +let globalstate_account = next_account_info(accounts_iter)?; +let payer_account = next_account_info(accounts_iter)?; +let system_program = next_account_info(accounts_iter)?; + +assert!(payer_account.is_signer, "Payer must be a signer"); +assert_eq!(globalstate_account.owner, program_id, "Invalid GlobalState Account Owner"); +assert_eq!(*system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner"); +assert!(mgroup_account.is_writable, "PDA Account is not writable"); + +let (expected_pda_account, bump_seed) = get_multicastgroup_pda(program_id, value.index); +assert_eq!(mgroup_account.key, &expected_pda_account, "Invalid MulticastGroup Pubkey"); +assert_eq!(bump_seed, value.bump_seed, "Invalid MulticastGroup Bump Seed"); +``` + +--- + +## 2. Input and Business Logic Validation + +- Validate and normalize all input arguments (e.g., using helpers like `validate_account_code`). +- Deserialize account data using the appropriate helper (e.g., `try_from`). +- Validate any business-specific invariants (e.g., allowlist membership). +- Check for account initialization state as needed. + +**Example:** +```rust +let code = validate_account_code(&value.code).map_err(|_| DoubleZeroError::InvalidAccountCode)?; +let mut globalstate = GlobalState::try_from(globalstate_account)?; +globalstate.account_index += 1; + +if !globalstate.foundation_allowlist.contains(payer_account.key) { + return Err(DoubleZeroError::NotAllowed.into()); +} + +if !mgroup_account.data_is_empty() { + return Err(ProgramError::AccountAlreadyInitialized); +} +``` + +--- + +## 3. State Construction and Mutation + +- Construct new state objects as needed, using validated and normalized data. +- Mutate in-memory state only after all checks and validations have passed. + +**Example:** +```rust +let multicastgroup = MulticastGroup { + account_type: AccountType::MulticastGroup, + owner: value.owner, + index: globalstate.account_index, + bump_seed, + tenant_pk: Pubkey::default(), + code, + multicast_ip: std::net::Ipv4Addr::UNSPECIFIED, + max_bandwidth: value.max_bandwidth, + status: MulticastGroupStatus::Pending, + publisher_count: 0, + subscriber_count: 0, +}; +``` + +--- + +## 4. State Serialization and Account Creation + +- Use the approved helpers (e.g., `try_acc_create`, `try_acc_write`) to create and write account data. +- Pass all required seeds and bump seeds for PDA creation. +- Ensure the payer is authorized to pay for the write if required. + +**Example:** +```rust +try_acc_create( + &multicastgroup, + mgroup_account, + payer_account, + system_program, + program_id, + &[ + SEED_PREFIX, + SEED_MULTICAST_GROUP, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], +)?; +try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; +``` + +--- + +## 5. Error Handling + +- Use explicit error returns for all failure cases. +- Avoid panics or unchecked unwraps in production code. +- Use descriptive error messages and custom error types where appropriate. + +--- + +## 6. Logging (Optional for Tests) + +- Use logging macros (e.g., `msg!`) for debugging and test builds as needed. + +--- + +## 7. Return + +- Return `Ok(())` on success. + +--- + +## 8. Summary Checklist + +- [ ] Parse and validate all accounts. +- [ ] Check signers, ownership, and PDA derivation. +- [ ] Validate and normalize input arguments. +- [ ] Deserialize and validate state. +- [ ] Check business logic and invariants. +- [ ] Construct and mutate state. +- [ ] Create and write account data. +- [ ] Handle errors explicitly. +- [ ] Log for debugging if needed. +- [ ] Return success. + +--- + +By following these steps, you ensure that new instructions are secure, robust, and consistent with the rest of the codebase. diff --git a/smartcontract/programs/doublezero-serviceability/src/accounts.rs b/smartcontract/programs/doublezero-serviceability/src/accounts.rs deleted file mode 100644 index 6300d74ab..000000000 --- a/smartcontract/programs/doublezero-serviceability/src/accounts.rs +++ /dev/null @@ -1,83 +0,0 @@ -use borsh::BorshSerialize; -use doublezero_program_common::create_account::try_create_account; -use solana_program::{ - account_info::AccountInfo, - entrypoint::ProgramResult, - program::invoke, - program_error::ProgramError, - pubkey::Pubkey, - system_instruction, system_program, - sysvar::{rent::Rent, Sysvar}, -}; - -pub trait AccountSize { - fn size(&self) -> usize; -} -pub trait AccountSeed { - fn seed(&self, seed: &mut Vec); -} - -pub fn write_account<'a, D: BorshSerialize + AccountSize + AccountSeed>( - account: &AccountInfo<'a>, - data: &D, - program_id: &Pubkey, - payer: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, -) -> ProgramResult { - let required_space = data.size(); - let rent = Rent::get()?; - let required_lamports = rent.minimum_balance(required_space); - - let mut seed: Vec = Vec::new(); - data.seed(&mut seed); - - if account.try_borrow_data()?.is_empty() { - try_create_account( - payer.key, - account.key, - account.lamports(), - required_space, - program_id, - &[account.clone(), payer.clone(), system_program.clone()], - &[seed.as_slice()], - )?; - } else { - let old_len = account.data_len(); - if old_len != required_space { - if required_space > old_len { - let payment = required_lamports.saturating_sub(account.lamports()); - if payment > 0 { - invoke( - &system_instruction::transfer(payer.key, account.key, payment), - &[account.clone(), payer.clone(), system_program.clone()], - )?; - } - } - - account.realloc(required_space, false)?; - } - } - - let mut account_data = &mut account.data.borrow_mut()[..]; - data.serialize(&mut account_data).unwrap(); - - Ok(()) -} - -pub fn account_close( - close_account: &AccountInfo, - receiving_account: &AccountInfo, -) -> ProgramResult { - // Transfere the rent lamports to the receiving account - **receiving_account.lamports.borrow_mut() = receiving_account - .lamports() - .checked_add(close_account.lamports()) - .ok_or(ProgramError::InsufficientFunds)?; - **close_account.lamports.borrow_mut() = 0; - - // Close the account - close_account.realloc(0, false)?; - close_account.assign(&system_program::ID); - - Ok(()) -} diff --git a/smartcontract/programs/doublezero-serviceability/src/addresses/doublezero_foundation.rs b/smartcontract/programs/doublezero-serviceability/src/addresses/_doublezero_foundation.rs similarity index 100% rename from smartcontract/programs/doublezero-serviceability/src/addresses/doublezero_foundation.rs rename to smartcontract/programs/doublezero-serviceability/src/addresses/_doublezero_foundation.rs diff --git a/smartcontract/programs/doublezero-serviceability/src/addresses/mod.rs b/smartcontract/programs/doublezero-serviceability/src/addresses/mod.rs index 60f7feeae..12e9244ce 100644 --- a/smartcontract/programs/doublezero-serviceability/src/addresses/mod.rs +++ b/smartcontract/programs/doublezero-serviceability/src/addresses/mod.rs @@ -1,4 +1,3 @@ pub mod devnet; -pub mod doublezero_foundation; pub mod mainnet; pub mod testnet; diff --git a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs index db6ea2478..c5500c51a 100644 --- a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs +++ b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs @@ -71,7 +71,7 @@ use crate::{ remove::process_remove_multicast_sub_allowlist, }, }, - closeaccount::process_deactivate_multicastgroup, + closeaccount::process_closeaccount_multicastgroup, create::process_create_multicastgroup, delete::process_delete_multicastgroup, reactivate::process_reactivate_multicastgroup, @@ -270,7 +270,7 @@ pub fn process_instruction( process_update_multicastgroup(program_id, accounts, &value)? } DoubleZeroInstruction::DeactivateMulticastGroup(value) => { - process_deactivate_multicastgroup(program_id, accounts, &value)? + process_closeaccount_multicastgroup(program_id, accounts, &value)? } DoubleZeroInstruction::AddMulticastGroupPubAllowlist(value) => { process_add_multicastgroup_pub_allowlist(program_id, accounts, &value)? diff --git a/smartcontract/programs/doublezero-serviceability/src/error.rs b/smartcontract/programs/doublezero-serviceability/src/error.rs index 72e2ee8a5..20b70ba7c 100644 --- a/smartcontract/programs/doublezero-serviceability/src/error.rs +++ b/smartcontract/programs/doublezero-serviceability/src/error.rs @@ -135,6 +135,8 @@ pub enum DoubleZeroError { SerializationFailure, // variant 64 #[error("Invalid argument")] InvalidArgument, // variant 65 + #[error("Invalid Foundation Allowlist: cannot be empty")] + InvalidFoundationAllowlist, // variant 66 } impl From for ProgramError { @@ -206,6 +208,7 @@ impl From for ProgramError { DoubleZeroError::AllocationFailed => ProgramError::Custom(63), DoubleZeroError::SerializationFailure => ProgramError::Custom(64), DoubleZeroError::InvalidArgument => ProgramError::Custom(65), + DoubleZeroError::InvalidFoundationAllowlist => ProgramError::Custom(66), } } } @@ -278,6 +281,7 @@ impl From for DoubleZeroError { 63 => DoubleZeroError::AllocationFailed, 64 => DoubleZeroError::SerializationFailure, 65 => DoubleZeroError::InvalidArgument, + 66 => DoubleZeroError::InvalidFoundationAllowlist, _ => DoubleZeroError::Custom(e), } } @@ -370,6 +374,7 @@ mod tests { AllocationFailed, SerializationFailure, InvalidArgument, + InvalidFoundationAllowlist, ]; for err in variants { let pe: ProgramError = err.clone().into(); diff --git a/smartcontract/programs/doublezero-serviceability/src/globalstate.rs b/smartcontract/programs/doublezero-serviceability/src/globalstate.rs deleted file mode 100644 index e5d521195..000000000 --- a/smartcontract/programs/doublezero-serviceability/src/globalstate.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::{ - seeds::*, - state::{accounttype::*, globalconfig::GlobalConfig, globalstate::GlobalState}, -}; -use borsh::BorshSerialize; -#[cfg(test)] -use solana_program::msg; -use solana_program::{ - account_info::AccountInfo, - program::invoke_signed, - system_instruction, - sysvar::{rent::Rent, Sysvar}, -}; -use std::io::Result; - -pub fn globalstate_get(globalstate_account: &AccountInfo) -> Result { - let data = &globalstate_account.data.borrow_mut(); - assert!(!data.is_empty(), "GlobalState Account not initialized"); - assert_eq!( - data[0], - AccountType::GlobalState as u8, - "Invalid GlobalState Account Type" - ); - - GlobalState::try_from(&data[..]).map_err(|e| std::io::Error::other(format!("{e:?}"))) -} - -pub fn globalstate_get_next(globalstate_account: &AccountInfo) -> Result { - let mut globalstate = globalstate_get(globalstate_account)?; - globalstate.account_index += 1; - - Ok(globalstate) -} - -pub fn globalstate_write( - globalstate_account: &AccountInfo, - globalstate: &GlobalState, -) -> Result<()> { - assert_eq!( - globalstate_account.data_len(), - globalstate.size(), - "Invalid GlobalState Account Size" - ); - - // Update GlobalState - let mut account_data = &mut globalstate_account.data.borrow_mut()[..]; - globalstate.serialize(&mut account_data)?; - - #[cfg(test)] - msg!("Updated: {:?}", globalstate); - - Ok(()) -} - -pub fn globalstate_write_with_realloc<'a>( - account: &AccountInfo<'a>, - instance: &GlobalState, - payer_account: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, - bump_seed: u8, -) { - let actual_len = account.data_len(); - let new_len = instance.size(); - - // Update the account - // Check if the account needs to be resized - // If so, realloc the account - { - if actual_len != new_len { - account - .realloc(new_len, false) - .expect("Unable to realloc the account"); - } - - let data = &mut account.data.borrow_mut(); - instance - .serialize(&mut &mut data[..]) - .expect("Unable to serialize"); - } - - // Check is the account needs more rent for the new space - // If so, transfer the required lamports from the payer account - // to the account - if new_len > actual_len { - let rent: Rent = Rent::get().expect("Unable to read rent"); - let required_lamports: u64 = rent.minimum_balance(new_len); - - if required_lamports > account.lamports() { - let payment: u64 = required_lamports - account.lamports(); - - #[cfg(test)] - msg!( - "Rent Required: {} Actual: {} Transfer: {}", - required_lamports, - account.lamports(), - payment - ); - - invoke_signed( - &system_instruction::transfer(payer_account.key, account.key, payment), - &[ - account.clone(), - payer_account.clone(), - system_program.clone(), - ], - &[&[SEED_PREFIX, SEED_GLOBALSTATE, &[bump_seed]]], - ) - .expect("Unable to pay rent"); - } - } -} - -pub fn globalconfig_write_with_realloc<'a>( - account: &AccountInfo<'a>, - instance: &GlobalConfig, - payer_account: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, - bump_seed: u8, -) { - let actual_len = account.data_len(); - let new_len = instance.size(); - - // Update the account - // Check if the account needs to be resized - // If so, realloc the account - { - if actual_len != new_len { - account - .realloc(new_len, false) - .expect("Unable to realloc the account"); - } - - let data = &mut account.data.borrow_mut(); - instance - .serialize(&mut &mut data[..]) - .expect("Unable to serialize"); - } - - // Check is the account needs more rent for the new space - // If so, transfer the required lamports from the payer account - // to the account - if new_len > actual_len { - let rent: Rent = Rent::get().expect("Unable to read rent"); - let required_lamports: u64 = rent.minimum_balance(new_len); - - if required_lamports > account.lamports() { - let payment: u64 = required_lamports - account.lamports(); - - #[cfg(test)] - msg!( - "Rent Required: {} Actual: {} Transfer: {}", - required_lamports, - account.lamports(), - payment - ); - - invoke_signed( - &system_instruction::transfer(payer_account.key, account.key, payment), - &[ - account.clone(), - payer_account.clone(), - system_program.clone(), - ], - &[&[SEED_PREFIX, SEED_CONFIG, &[bump_seed]]], - ) - .expect("Unable to pay rent"); - } - } -} diff --git a/smartcontract/programs/doublezero-serviceability/src/helper.rs b/smartcontract/programs/doublezero-serviceability/src/helper.rs index 0f941acbd..1335ad34c 100644 --- a/smartcontract/programs/doublezero-serviceability/src/helper.rs +++ b/smartcontract/programs/doublezero-serviceability/src/helper.rs @@ -1,201 +1,11 @@ -use crate::{ - error::Validate, - seeds::*, - state::{accounttype::*, globalconfig::GlobalConfig}, -}; -use borsh::{BorshDeserialize, BorshSerialize}; -use solana_program::{ - account_info::AccountInfo, - entrypoint::ProgramResult, - program::invoke_signed, - program_error::ProgramError, - pubkey::Pubkey, - system_instruction, system_program, - sysvar::{rent::Rent, Sysvar}, -}; +use crate::state::globalconfig::GlobalConfig; +use borsh::BorshDeserialize; +use solana_program::program_error::ProgramError; use std::{ - fmt::{self, Debug}, + fmt::{self}, net::Ipv4Addr, }; -use doublezero_program_common::create_account::try_create_account; -#[cfg(test)] -use solana_program::msg; - -pub fn account_create<'a, T>( - account: &AccountInfo<'a>, - instance: &T, - payer_account: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, - program_id: &Pubkey, -) -> ProgramResult -where - T: AccountTypeInfo + BorshSerialize + Validate + Debug, -{ - // Validate the instance - instance.validate()?; - - let account_space = AccountTypeInfo::size(instance); - - #[cfg(test)] - { - let rent = Rent::get().expect("Unable to get rent"); - let required_lamports = rent.minimum_balance(account_space); - msg!("Rent: {}", required_lamports); - } - // Create the index account - try_create_account( - payer_account.key, // Account paying for the new account - account.key, // Account to be created - account.lamports(), // Current amount of lamports on the new account - account_space, // Size in bytes to allocate for the data field - program_id, // Set program owner to our program - &[ - account.clone(), - payer_account.clone(), - system_program.clone(), - ], - &[ - SEED_PREFIX, - instance.seed(), - &instance.index().to_le_bytes(), - &[instance.bump_seed()], - ], - )?; - - let mut account_data = &mut account.data.borrow_mut()[..]; - instance.serialize(&mut account_data).unwrap(); - - #[cfg(test)] - msg!("Created: {:?}", instance); - - Ok(()) -} - -pub fn account_create_with_seed<'a, T>( - account: &AccountInfo<'a>, - instance: &T, - payer_account: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, - program_id: &Pubkey, - new_account_signer_seeds: &[&[u8]], -) -> ProgramResult -where - T: AccountTypeInfo + BorshSerialize + Validate + Debug, -{ - // Validate the instance - instance.validate()?; - - let account_space = AccountTypeInfo::size(instance); - - #[cfg(test)] - { - let rent = Rent::get().expect("Unable to get rent"); - let required_lamports = rent.minimum_balance(account_space); - msg!("Rent: {}", required_lamports); - } - // Create the index account - try_create_account( - payer_account.key, // Account paying for the new account - account.key, // Account to be created - account.lamports(), // Current amount of lamports on the new account - account_space, // Size in bytes to allocate for the data field - program_id, // Set program owner to our program - &[ - account.clone(), - payer_account.clone(), - system_program.clone(), - ], - new_account_signer_seeds, - )?; - - let mut account_data = &mut account.data.borrow_mut()[..]; - instance.serialize(&mut account_data).unwrap(); - - #[cfg(test)] - msg!("Created: {:?}", instance); - - Ok(()) -} - -pub fn account_write<'a, T>( - account: &AccountInfo<'a>, - instance: &T, - payer_account: &AccountInfo<'a>, - system_program: &AccountInfo<'a>, -) -> ProgramResult -where - T: AccountTypeInfo + BorshSerialize + Validate + Debug, -{ - // Validate the instance - instance.validate()?; - - let actual_len = account.data_len(); - let new_len = instance.size(); - { - if actual_len != new_len { - account - .realloc(new_len, false) - .expect("Unable to realoc the account"); - } - - let data = &mut account.data.borrow_mut(); - instance.serialize(&mut &mut data[..])?; - } - - if actual_len < new_len { - let rent = Rent::get().expect("Unble to read rent"); - let required_lamports = rent.minimum_balance(new_len); - - if required_lamports > account.lamports() { - let payment = required_lamports - account.lamports(); - - #[cfg(test)] - msg!( - "Rent Requered: {} Actual: {} Transfer: {}", - required_lamports, - account.lamports(), - payment - ); - - invoke_signed( - &system_instruction::transfer(payer_account.key, account.key, payment), - &[ - account.clone(), - payer_account.clone(), - system_program.clone(), - ], - &[&[ - SEED_PREFIX, - instance.seed(), - &instance.index().to_le_bytes(), - &[instance.bump_seed()], - ]], - )?; - } - } - - Ok(()) -} - -pub fn account_close( - close_account: &AccountInfo, - receiving_account: &AccountInfo, -) -> ProgramResult { - // Transfere the rent lamports to the receiving account - **receiving_account.lamports.borrow_mut() = receiving_account - .lamports() - .checked_add(close_account.lamports()) - .ok_or(ProgramError::InsufficientFunds)?; - **close_account.lamports.borrow_mut() = 0; - - // Close the account - close_account.realloc(0, false)?; - close_account.assign(&system_program::ID); - - Ok(()) -} - pub fn assign_bgp_community(globalconfig: &mut GlobalConfig) -> u16 { let assigned = globalconfig.next_bgp_community; globalconfig.next_bgp_community = assigned.saturating_add(1); diff --git a/smartcontract/programs/doublezero-serviceability/src/lib.rs b/smartcontract/programs/doublezero-serviceability/src/lib.rs index 087a4326f..d133d82ec 100644 --- a/smartcontract/programs/doublezero-serviceability/src/lib.rs +++ b/smartcontract/programs/doublezero-serviceability/src/lib.rs @@ -1,19 +1,17 @@ #![allow(unexpected_cfgs)] -pub mod entrypoint; -mod globalstate; -mod helper; -mod min_version; - -pub mod accounts; pub mod addresses; +pub mod entrypoint; pub mod error; +mod helper; pub mod id_allocator; pub mod instructions; pub mod ip_allocator; +mod min_version; pub mod pda; pub mod processors; pub mod programversion; pub mod resource; pub mod seeds; +mod serializer; pub mod state; diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/check_status.rs b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/check_status.rs index 38ef90833..347798061 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/check_status.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/check_status.rs @@ -1,12 +1,12 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - state::{accesspass::AccessPass, accounttype::AccountTypeInfo}, + serializer::try_acc_write, + state::{accesspass::AccessPass, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -64,9 +64,14 @@ pub fn process_check_status_access_pass( accesspass_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key && !globalstate.foundation_allowlist.contains(payer_account.key) { @@ -83,13 +88,7 @@ pub fn process_check_status_access_pass( // Update status accesspass.update_status()?; - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", accesspass); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/close.rs b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/close.rs index 1e427df49..0671428bc 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/close.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/close.rs @@ -1,6 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::account_close, - state::accounttype::AccountType, + error::DoubleZeroError, + serializer::try_acc_close, + state::{accounttype::AccountType, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -63,9 +64,14 @@ pub fn process_close_access_pass( accesspass_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -81,7 +87,7 @@ pub fn process_close_access_pass( msg!("Failed to borrow account data, cannot close"); } - account_close(accesspass_account, payer_account)?; + try_acc_close(accesspass_account, payer_account)?; msg!("Access pass closed"); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs index da6f9eae6..40fb51ccc 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs @@ -1,19 +1,17 @@ -use core::fmt; -use std::net::Ipv4Addr; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, pda::*, seeds::{SEED_ACCESS_PASS, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, state::{ accesspass::{AccessPass, AccessPassStatus, AccessPassType, ALLOW_MULTIPLE_IP, IS_DYNAMIC}, - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, + globalstate::GlobalState, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; -use doublezero_program_common::{resize_account::resize_account_if_needed, try_create_account}; +use core::fmt; use solana_program::{ account_info::{next_account_info, AccountInfo}, clock::Clock, @@ -25,6 +23,7 @@ use solana_program::{ system_instruction, sysvar::Sysvar, }; +use std::net::Ipv4Addr; // Value to rent exempt two `User` accounts + configurable amount for connect/disconnect txns // `User` account size assumes a single publisher and subscriber pubkey registered @@ -91,9 +90,14 @@ pub fn process_set_access_pass( accesspass_account.key, &expected_pda_account, "Invalid AccessPass PubKey" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.sentinel_authority_pk != *payer_account.key && !globalstate.foundation_allowlist.contains(payer_account.key) { @@ -129,6 +133,7 @@ pub fn process_set_access_pass( flags |= ALLOW_MULTIPLE_IP; } + // If account does not exist, create it if *accesspass_account.owner == solana_program::system_program::id() { let accesspass = AccessPass { account_type: AccountType::AccessPass, @@ -145,13 +150,12 @@ pub fn process_set_access_pass( flags, }; - try_create_account( - payer_account.key, // Account paying for the new account - accesspass_account.key, // Account to be created - accesspass_account.lamports(), // Current amount of lamports on the new account - accesspass.size(), // Size in bytes to allocate for the data field - program_id, // Set program owner to our program - accounts, + try_acc_create( + &accesspass, + accesspass_account, + payer_account, + system_program, + program_id, &[ SEED_PREFIX, SEED_ACCESS_PASS, @@ -160,11 +164,12 @@ pub fn process_set_access_pass( &[bump_seed], ], )?; - accesspass.try_serialize(accesspass_account)?; #[cfg(test)] msg!("Created: {:?}", accesspass); } else { + // Read or create Access Pass + // Old bug where close accounts were not fully zeroed out instead of being closed let mut accesspass = if !accesspass_account.data_is_empty() { assert_eq!( accesspass_account.owner, program_id, @@ -189,22 +194,19 @@ pub fn process_set_access_pass( } }; + // Update fields accesspass.accesspass_type = value.accesspass_type; accesspass.last_access_epoch = value.last_access_epoch; accesspass.flags = flags; - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + // Write back updated Access Pass + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", accesspass); } + // Airdrop rent exempt + configured lamports to user_payer account let deposit = Rent::get() .unwrap() .minimum_balance(AIRDROP_USER_RENT_LAMPORTS_BYTES) diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/add.rs b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/add.rs index 0d11b4fdb..3a85b2112 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/add.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/add.rs @@ -1,12 +1,9 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -34,7 +31,7 @@ pub fn process_add_device_allowlist_globalconfig( ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; @@ -45,23 +42,34 @@ pub fn process_add_device_allowlist_globalconfig( assert!(payer_account.is_signer, "Payer must be a signer"); // Check the owner of the accounts - assert_eq!(pda_account.owner, program_id, "Invalid PDA Account Owner"); + assert_eq!( + globalstate_account.owner, program_id, + "Invalid PDA Account Owner" + ); assert_eq!( *system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner" ); // Check if the account is writable - assert!(pda_account.is_writable, "PDA Account is not writable"); + assert!( + globalstate_account.is_writable, + "PDA Account is not writable" + ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(pda_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -71,13 +79,8 @@ pub fn process_add_device_allowlist_globalconfig( } globalstate.device_allowlist.push(value.pubkey); - globalstate_write_with_realloc( - pda_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/remove.rs b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/remove.rs index 0cfbd3899..4c7f80731 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/remove.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/remove.rs @@ -1,12 +1,9 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -33,7 +30,7 @@ pub fn process_remove_device_allowlist_globalconfig( ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; @@ -44,36 +41,41 @@ pub fn process_remove_device_allowlist_globalconfig( assert!(payer_account.is_signer, "Payer must be a signer"); // Check the owner of the accounts - assert_eq!(pda_account.owner, program_id, "Invalid PDA Account Owner"); + assert_eq!( + globalstate_account.owner, program_id, + "Invalid PDA Account Owner" + ); assert_eq!( *system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner" ); // Check if the account is writable - assert!(pda_account.is_writable, "PDA Account is not writable"); + assert!( + globalstate_account.is_writable, + "PDA Account is not writable" + ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(pda_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } globalstate.device_allowlist.retain(|x| x != &value.pubkey); - globalstate_write_with_realloc( - pda_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/add.rs b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/add.rs index 373b49128..6130eeba3 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/add.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/add.rs @@ -1,9 +1,5 @@ -use std::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -15,6 +11,7 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, }; +use std::fmt; #[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone, Default)] pub struct AddFoundationAllowlistArgs { @@ -34,7 +31,7 @@ pub fn process_add_foundation_allowlist_globalconfig( ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; @@ -45,23 +42,34 @@ pub fn process_add_foundation_allowlist_globalconfig( assert!(payer_account.is_signer, "Payer must be a signer"); // Check the owner of the accounts - assert_eq!(pda_account.owner, program_id, "Invalid PDA Account Owner"); + assert_eq!( + globalstate_account.owner, program_id, + "Invalid PDA Account Owner" + ); assert_eq!( *system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner" ); // Check if the account is writable - assert!(pda_account.is_writable, "PDA Account is not writable"); + assert!( + globalstate_account.is_writable, + "PDA Account is not writable" + ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(pda_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -71,13 +79,8 @@ pub fn process_add_foundation_allowlist_globalconfig( } globalstate.foundation_allowlist.push(value.pubkey); - globalstate_write_with_realloc( - pda_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/remove.rs b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/remove.rs index becbe0e0d..287ca2950 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/remove.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/foundation/remove.rs @@ -1,12 +1,9 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -33,7 +30,7 @@ pub fn process_remove_foundation_allowlist_globalconfig( ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; @@ -47,23 +44,34 @@ pub fn process_remove_foundation_allowlist_globalconfig( assert!(payer_account.is_signer, "Payer must be a signer"); // Check the owner of the accounts - assert_eq!(pda_account.owner, program_id, "Invalid PDA Account Owner"); + assert_eq!( + globalstate_account.owner, program_id, + "Invalid PDA Account Owner" + ); assert_eq!( *system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner" ); // Check if the account is writable - assert!(pda_account.is_writable, "PDA Account is not writable"); + assert!( + globalstate_account.is_writable, + "PDA Account is not writable" + ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(pda_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -81,13 +89,8 @@ pub fn process_remove_foundation_allowlist_globalconfig( .foundation_allowlist .retain(|x| x != &value.pubkey); - globalstate_write_with_realloc( - pda_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/add.rs b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/add.rs index 7e003115d..cb0e38c94 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/add.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/add.rs @@ -1,12 +1,9 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -34,7 +31,7 @@ pub fn process_add_user_allowlist( ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; @@ -45,23 +42,34 @@ pub fn process_add_user_allowlist( assert!(payer_account.is_signer, "Payer must be a signer"); // Check the owner of the accounts - assert_eq!(pda_account.owner, program_id, "Invalid PDA Account Owner"); + assert_eq!( + globalstate_account.owner, program_id, + "Invalid PDA Account Owner" + ); assert_eq!( *system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner" ); // Check if the account is writable - assert!(pda_account.is_writable, "PDA Account is not writable"); + assert!( + globalstate_account.is_writable, + "PDA Account is not writable" + ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(pda_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -71,13 +79,8 @@ pub fn process_add_user_allowlist( } globalstate.user_allowlist.push(value.pubkey); - globalstate_write_with_realloc( - pda_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/remove.rs b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/remove.rs index 8350121d4..b75c238c4 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/remove.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/allowlist/user/remove.rs @@ -1,12 +1,9 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -33,7 +30,7 @@ pub fn process_remove_user_allowlist( ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; @@ -44,36 +41,42 @@ pub fn process_remove_user_allowlist( assert!(payer_account.is_signer, "Payer must be a signer"); // Check the owner of the accounts - assert_eq!(pda_account.owner, program_id, "Invalid PDA Account Owner"); + assert_eq!( + globalstate_account.owner, program_id, + "Invalid PDA Account Owner" + ); assert_eq!( *system_program.unsigned_key(), solana_program::system_program::id(), "Invalid System Program Account Owner" ); // Check if the account is writable - assert!(pda_account.is_writable, "PDA Account is not writable"); + assert!( + globalstate_account.is_writable, + "PDA Account is not writable" + ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(pda_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } globalstate.user_allowlist.retain(|x| x != &value.pubkey); - globalstate_write_with_realloc( - pda_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/create.rs index c8d21db36..1c90f85e4 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/create.rs @@ -1,9 +1,9 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::*, pda::*, - state::{accounttype::AccountType, contributor::*}, + seeds::{SEED_CONTRIBUTOR, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, + state::{accounttype::AccountType, contributor::*, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -72,8 +72,16 @@ pub fn process_create_contributor( contributor_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); + // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; + if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -86,7 +94,7 @@ pub fn process_create_contributor( ); // Check if the account is already initialized - if !contributor_account.data.borrow().is_empty() { + if !contributor_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } @@ -116,14 +124,20 @@ pub fn process_create_contributor( &[], )?; - account_create( - contributor_account, + try_acc_create( &contributor, + contributor_account, payer_account, system_program, program_id, + &[ + SEED_PREFIX, + SEED_CONTRIBUTOR, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], )?; - globalstate_write(globalstate_account, &globalstate)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/delete.rs index 3508c656d..c78f813f4 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/delete.rs @@ -1,5 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::contributor::*, + error::DoubleZeroError, + serializer::try_acc_close, + state::{contributor::*, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -57,9 +59,14 @@ pub fn process_delete_contributor( contributor_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -72,7 +79,7 @@ pub fn process_delete_contributor( return Err(DoubleZeroError::ReferenceCountNotZero.into()); } - account_close(contributor_account, payer_account)?; + try_acc_close(contributor_account, payer_account)?; #[cfg(test)] msg!("Deleted: {:?}", contributor_account); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/resume.rs b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/resume.rs index f8f4001c6..4350a10a0 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/resume.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/resume.rs @@ -1,10 +1,12 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::contributor::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{contributor::*, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -57,9 +59,14 @@ pub fn process_resume_contributor( contributor_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -67,12 +74,7 @@ pub fn process_resume_contributor( let mut contributor: Contributor = Contributor::try_from(contributor_account)?; contributor.status = ContributorStatus::Activated; - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; #[cfg(test)] msg!("Resumed: {:?}", contributor); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/suspend.rs index 45b12e6a2..007780c35 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/suspend.rs @@ -1,10 +1,11 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::contributor::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{contributor::*, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -58,9 +59,14 @@ pub fn process_suspend_contributor( contributor_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -68,12 +74,7 @@ pub fn process_suspend_contributor( let mut contributor: Contributor = Contributor::try_from(contributor_account)?; contributor.status = ContributorStatus::Suspended; - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; #[cfg(test)] msg!("Suspended: {:?}", contributor); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/update.rs index aaf54baa3..226f9eb28 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/contributor/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/contributor/update.rs @@ -1,5 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::contributor::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{contributor::*, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -65,9 +67,14 @@ pub fn process_update_contributor( contributor_account.is_writable, "PDA Account is not writable" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); let mut contributor = Contributor::try_from(contributor_account)?; - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; let only_ops_manager_update = value.code.is_none() && value.owner.is_none() && value.ops_manager_pk.is_some(); @@ -95,12 +102,7 @@ pub fn process_update_contributor( if let Some(ref ops_manager_pk) = value.ops_manager_pk { contributor.ops_manager_pk = *ops_manager_pk; } - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", contributor); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/activate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/activate.rs index 4a2ee936c..4ff5a1d37 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/activate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/activate.rs @@ -1,8 +1,11 @@ -use core::fmt; - -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::device::*}; +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState}, +}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -27,7 +30,7 @@ pub fn process_activate_device(program_id: &Pubkey, accounts: &[AccountInfo]) -> let device_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_activate_device()"); @@ -42,7 +45,7 @@ pub fn process_activate_device(program_id: &Pubkey, accounts: &[AccountInfo]) -> return Err(ProgramError::IncorrectProgramId); } - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -55,7 +58,7 @@ pub fn process_activate_device(program_id: &Pubkey, accounts: &[AccountInfo]) -> device.status = DeviceStatus::Activated; - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Activated: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/closeaccount.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/closeaccount.rs index 097de5198..273a5ddef 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/closeaccount.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/closeaccount.rs @@ -1,8 +1,10 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{contributor::Contributor, device::*, exchange::Exchange, location::Location}, + serializer::{try_acc_close, try_acc_write}, + state::{ + contributor::Contributor, device::*, exchange::Exchange, globalstate::GlobalState, + location::Location, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -38,7 +40,7 @@ pub fn process_closeaccount_device( let exchange_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_closeaccount_device({:?})", _value); @@ -66,7 +68,7 @@ pub fn process_closeaccount_device( assert!(device_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -92,15 +94,10 @@ pub fn process_closeaccount_device( location.reference_count = location.reference_count.saturating_sub(1); exchange.reference_count = exchange.reference_count.saturating_sub(1); - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; - account_write(location_account, &location, payer_account, system_program)?; - account_write(exchange_account, &exchange, payer_account, system_program)?; - account_close(device_account, owner_account)?; + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; + try_acc_write(&location, location_account, payer_account, accounts)?; + try_acc_write(&exchange, exchange_account, payer_account, accounts)?; + try_acc_close(device_account, owner_account)?; #[cfg(test)] msg!("CloseAccount: Device closed"); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/create.rs index cb758d84a..fc88578be 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/create.rs @@ -1,11 +1,11 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::{account_create, account_write}, pda::get_device_pda, + seeds::{SEED_DEVICE, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, state::{ accounttype::AccountType, contributor::Contributor, device::*, exchange::Exchange, - location::Location, + globalstate::GlobalState, location::Location, }, }; use borsh::BorshSerialize; @@ -89,11 +89,18 @@ pub fn process_create_device( globalstate_account.owner, program_id, "Invalid GlobalState Account Owner" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - if !device_account.data.borrow().is_empty() { + if !device_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; + assert_eq!(globalstate.account_type, AccountType::GlobalState); let mut contributor = Contributor::try_from(contributor_account)?; @@ -150,22 +157,24 @@ pub fn process_create_device( max_users: 0, // Initially, the Device is locked and must be activated by modifying the maximum number of users. }; - account_create( - device_account, + try_acc_create( &device, + device_account, payer_account, system_program, program_id, + &[ + SEED_PREFIX, + SEED_DEVICE, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], )?; - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; - account_write(location_account, &location, payer_account, system_program)?; - account_write(exchange_account, &exchange, payer_account, system_program)?; - globalstate_write(globalstate_account, &globalstate)?; + + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; + try_acc_write(&location, location_account, payer_account, accounts)?; + try_acc_write(&exchange, exchange_account, payer_account, accounts)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/delete.rs index c5f156bae..d0a4d951e 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/delete.rs @@ -1,8 +1,9 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountType, contributor::Contributor, device::*}, + serializer::try_acc_write, + state::{ + accounttype::AccountType, contributor::Contributor, device::*, globalstate::GlobalState, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -62,8 +63,13 @@ pub fn process_delete_device( "Invalid System Program Account Owner" ); assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -82,7 +88,7 @@ pub fn process_delete_device( device.status = DeviceStatus::Deleting; - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Deleting: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/activate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/activate.rs index 80d742c27..32e6c6429 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/activate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/activate.rs @@ -1,13 +1,11 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::*, interface::InterfaceStatus}, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState, interface::InterfaceStatus}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; use doublezero_program_common::types::NetworkV4; #[cfg(test)] use solana_program::msg; @@ -45,7 +43,7 @@ pub fn process_activate_device_interface( let device_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_activate_device_interface()"); @@ -60,7 +58,7 @@ pub fn process_activate_device_interface( return Err(ProgramError::IncorrectProgramId); } - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -82,7 +80,7 @@ pub fn process_activate_device_interface( device.interfaces[idx] = updated_iface.to_interface(); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Activated: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/create.rs index f2725d3d7..59b0dc7fe 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/create.rs @@ -1,11 +1,11 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get_next, - helper::account_write, + serializer::try_acc_write, state::{ accounttype::AccountType, contributor::Contributor, device::*, + globalstate::GlobalState, interface::{ CurrentInterfaceVersion, InterfaceCYOA, InterfaceDIA, InterfaceStatus, InterfaceType, LoopbackType, RoutingMode, @@ -59,7 +59,7 @@ pub fn process_create_device_interface( let contributor_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_create_device_interface({:?})", value); @@ -80,7 +80,7 @@ pub fn process_create_device_interface( assert!(device_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get_next(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -122,7 +122,7 @@ pub fn process_create_device_interface( .to_interface(), ); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/delete.rs index 9fc9b90c7..8aaed3bd7 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/delete.rs @@ -1,9 +1,9 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, + serializer::try_acc_write, state::{ - accounttype::AccountType, contributor::Contributor, device::*, interface::InterfaceStatus, + accounttype::AccountType, contributor::Contributor, device::*, globalstate::GlobalState, + interface::InterfaceStatus, }, }; use borsh::BorshSerialize; @@ -66,8 +66,13 @@ pub fn process_delete_device_interface( "Invalid System Program Account Owner" ); assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -87,7 +92,7 @@ pub fn process_delete_device_interface( iface.status = InterfaceStatus::Deleting; device.interfaces[idx] = iface.to_interface(); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Deleting interface: {} from {:?}", value.name, device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/reject.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/reject.rs index 2c7c4f7a8..e36afa4f9 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/reject.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/reject.rs @@ -1,13 +1,11 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::*, interface::InterfaceStatus}, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState, interface::InterfaceStatus}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -38,7 +36,7 @@ pub fn process_reject_device_interface( let device_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_reject_device_interface()"); @@ -53,7 +51,7 @@ pub fn process_reject_device_interface( return Err(ProgramError::IncorrectProgramId); } - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -67,7 +65,7 @@ pub fn process_reject_device_interface( iface.status = InterfaceStatus::Rejected; device.interfaces[idx] = iface.to_interface(); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Rejected: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/remove.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/remove.rs index de725f22f..38b078710 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/remove.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/remove.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::*, interface::InterfaceStatus}, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState, interface::InterfaceStatus}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -36,7 +35,7 @@ pub fn process_remove_device_interface( let device_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_remove_device_interface({:?})", value); @@ -56,7 +55,7 @@ pub fn process_remove_device_interface( assert!(device_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -71,7 +70,7 @@ pub fn process_remove_device_interface( } device.interfaces.remove(idx); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Remove: Device Interface removed"); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/unlink.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/unlink.rs index ed9de836f..025754fb7 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/unlink.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/unlink.rs @@ -1,13 +1,11 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::*, interface::InterfaceStatus}, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState, interface::InterfaceStatus}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; use doublezero_program_common::types::NetworkV4; #[cfg(test)] use solana_program::msg; @@ -39,7 +37,7 @@ pub fn process_unlink_device_interface( let device_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_unlink_device_interface()"); @@ -54,7 +52,7 @@ pub fn process_unlink_device_interface( return Err(ProgramError::IncorrectProgramId); } - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -73,7 +71,7 @@ pub fn process_unlink_device_interface( iface.ip_net = NetworkV4::default(); device.interfaces[idx] = iface.to_interface(); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Unlinked: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/update.rs index 6edc7ee5c..0eeff6781 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/interface/update.rs @@ -1,10 +1,10 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, + serializer::try_acc_write, state::{ accounttype::AccountType, device::*, + globalstate::GlobalState, interface::{InterfaceCYOA, InterfaceDIA, InterfaceStatus, LoopbackType, RoutingMode}, }, }; @@ -96,8 +96,13 @@ pub fn process_update_device_interface( ); // Check if the account is writable assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); if !globalstate.foundation_allowlist.contains(payer_account.key) { @@ -153,7 +158,7 @@ pub fn process_update_device_interface( // until we have release V2 version for interfaces, always convert to v1 device.interfaces[idx] = iface.to_interface(); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/reject.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/reject.rs index 9e9d62bb6..3c0fa22e6 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/reject.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/reject.rs @@ -1,7 +1,10 @@ +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState}, +}; use core::fmt; -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::device::*}; - use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use solana_program::{ @@ -55,8 +58,13 @@ pub fn process_reject_device( "Invalid System Program Account Owner" ); assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -70,7 +78,7 @@ pub fn process_reject_device( device.status = DeviceStatus::Rejected; msg!("Reason: {:?}", value.reason); - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Rejectd: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/resume.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/resume.rs index d8b1d85bd..9ff0e6087 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/resume.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/resume.rs @@ -1,13 +1,13 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountType, contributor::Contributor, device::*}, + serializer::try_acc_write, + state::{ + accounttype::AccountType, contributor::Contributor, device::*, globalstate::GlobalState, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -63,8 +63,13 @@ pub fn process_resume_device( "Invalid System Program Account Owner" ); assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -78,7 +83,7 @@ pub fn process_resume_device( let mut device: Device = Device::try_from(device_account)?; device.status = DeviceStatus::Activated; - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Resumed: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/suspend.rs index aedf52110..bb0244a1f 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/suspend.rs @@ -1,13 +1,13 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountType, contributor::Contributor, device::*}, + serializer::try_acc_write, + state::{ + accounttype::AccountType, contributor::Contributor, device::*, globalstate::GlobalState, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -63,8 +63,13 @@ pub fn process_suspend_device( "Invalid System Program Account Owner" ); assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -78,7 +83,7 @@ pub fn process_suspend_device( let mut device: Device = Device::try_from(device_account)?; device.status = DeviceStatus::Suspended; - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Suspended: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/device/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/device/update.rs index efa8867d4..b27541c2d 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/device/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/device/update.rs @@ -1,8 +1,10 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountType, contributor::Contributor, device::*, location::Location}, + serializer::try_acc_write, + state::{ + accounttype::AccountType, contributor::Contributor, device::*, globalstate::GlobalState, + location::Location, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -115,8 +117,13 @@ pub fn process_update_device( ); // Check if the account is writable assert!(device_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -184,18 +191,8 @@ pub fn process_update_device( // Set new location pk in device device.location_pk = *location_new_account.key; - account_write( - location_old_account, - &location_old, - payer_account, - system_program, - )?; - account_write( - location_new_account, - &location_new, - payer_account, - system_program, - )?; + try_acc_write(&location_old, location_old_account, payer_account, accounts)?; + try_acc_write(&location_new, location_new_account, payer_account, accounts)?; } } @@ -220,7 +217,7 @@ pub fn process_update_device( } } - account_write(device_account, &device, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", device); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/create.rs index 8d794359d..641cb9281 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/create.rs @@ -1,18 +1,19 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::{globalconfig_write_with_realloc, globalstate_get_next, globalstate_write}, - helper::*, + helper::assign_bgp_community, pda::*, + seeds::{SEED_EXCHANGE, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, state::{ accounttype::AccountType, exchange::{Exchange, ExchangeStatus}, globalconfig::GlobalConfig, + globalstate::GlobalState, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; use doublezero_program_common::validate_account_code; #[cfg(test)] use solana_program::msg; @@ -81,22 +82,30 @@ pub fn process_create_exchange( ); // Check if the account is writable assert!(exchange_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); + // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; + if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } // We need to access globalconfig in order to assign BGP community - let mut globalconfig = GlobalConfig::try_from(&globalconfig_account.data.borrow()[..])?; - let (globalconfig_pda, globalconfig_bump_seed) = get_globalconfig_pda(program_id); + let mut globalconfig = GlobalConfig::try_from(globalconfig_account)?; + let (globalconfig_pda, _) = get_globalconfig_pda(program_id); assert_eq!( globalconfig_account.key, &globalconfig_pda, "Invalid GlobalConfig PubKey" ); // Check if the account is already initialized - if !exchange_account.data.borrow().is_empty() { + if !exchange_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } @@ -125,21 +134,21 @@ pub fn process_create_exchange( status: ExchangeStatus::Activated, }; - account_create( - exchange_account, + try_acc_create( &exchange, + exchange_account, payer_account, system_program, program_id, + &[ + SEED_PREFIX, + SEED_EXCHANGE, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], )?; - globalstate_write(globalstate_account, &globalstate)?; - globalconfig_write_with_realloc( - globalconfig_account, - &globalconfig, - payer_account, - system_program, - globalconfig_bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + try_acc_write(&globalconfig, globalconfig_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/delete.rs index ea023f140..b507d143e 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/delete.rs @@ -1,10 +1,11 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::exchange::Exchange, + error::DoubleZeroError, + serializer::try_acc_close, + state::{exchange::Exchange, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -55,9 +56,14 @@ pub fn process_delete_exchange( "Invalid System Program Account Owner" ); assert!(exchange_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -68,7 +74,7 @@ pub fn process_delete_exchange( return Err(DoubleZeroError::ReferenceCountNotZero.into()); } - account_close(exchange_account, payer_account)?; + try_acc_close(exchange_account, payer_account)?; #[cfg(test)] msg!("Deleted: {:?}", exchange_account); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/resume.rs b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/resume.rs index 39c2e2614..74ea028ab 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/resume.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/resume.rs @@ -1,13 +1,14 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::account_write, - state::exchange::{Exchange, ExchangeStatus}, + serializer::try_acc_write, + state::{ + exchange::{Exchange, ExchangeStatus}, + globalstate::GlobalState, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -59,9 +60,14 @@ pub fn process_resume_exchange( ); // Check if the account is writable assert!(exchange_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse accounts - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; let mut exchange: Exchange = Exchange::try_from(exchange_account)?; // Authorization: @@ -72,7 +78,7 @@ pub fn process_resume_exchange( exchange.status = ExchangeStatus::Activated; - account_write(exchange_account, &exchange, payer_account, system_program)?; + try_acc_write(&exchange, exchange_account, payer_account, accounts)?; #[cfg(test)] msg!("Resumed: {:?}", exchange); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/setdevice.rs b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/setdevice.rs index ce0ca981a..72e7744cd 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/setdevice.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/setdevice.rs @@ -1,13 +1,11 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::Device, exchange::*}, + serializer::try_acc_write, + state::{device::Device, exchange::*, globalstate::GlobalState}, }; use borsh::{BorshDeserialize, BorshSerialize}; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; - #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -79,8 +77,14 @@ pub fn process_setdevice_exchange( ); // Check if the account is writable assert!(exchange_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); + // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -124,8 +128,8 @@ pub fn process_setdevice_exchange( device.reference_count -= 1; } - account_write(device_account, &device, payer_account, system_program)?; - account_write(exchange_account, &exchange, payer_account, system_program)?; + try_acc_write(&device, device_account, payer_account, accounts)?; + try_acc_write(&exchange, exchange_account, payer_account, accounts)?; #[cfg(test)] msg!("SetDevice: {:?}", exchange); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/suspend.rs index c0db7e8f0..583456056 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/suspend.rs @@ -1,4 +1,8 @@ -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::exchange::*}; +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{exchange::*, globalstate::GlobalState}, +}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; @@ -53,9 +57,14 @@ pub fn process_suspend_exchange( ); // Check if the account is writable assert!(exchange_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); // Parse accounts - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; let mut exchange: Exchange = Exchange::try_from(exchange_account)?; // Authorization: @@ -66,7 +75,7 @@ pub fn process_suspend_exchange( exchange.status = ExchangeStatus::Suspended; - account_write(exchange_account, &exchange, payer_account, system_program)?; + try_acc_write(&exchange, exchange_account, payer_account, accounts)?; #[cfg(test)] msg!("Suspended: {:?}", exchange); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/update.rs index 92440c4cb..57f70b609 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/exchange/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/exchange/update.rs @@ -1,14 +1,13 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - globalstate::{globalconfig_write_with_realloc, globalstate_get}, - helper::*, + helper::assign_bgp_community, pda::get_globalconfig_pda, - state::{exchange::Exchange, globalconfig::GlobalConfig}, + serializer::try_acc_write, + state::{exchange::Exchange, globalconfig::GlobalConfig, globalstate::GlobalState}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; use doublezero_program_common::validate_account_code; #[cfg(test)] use solana_program::msg; @@ -76,15 +75,21 @@ pub fn process_update_exchange( ); // Check if the account is writable assert!(exchange_account.is_writable, "PDA Account is not writable"); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); + // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } // We need to access globalconfig in order to assign BGP community - let mut globalconfig = GlobalConfig::try_from(&globalconfig_account.data.borrow()[..])?; - let (globalconfig_pda, globalconfig_bump_seed) = get_globalconfig_pda(program_id); + let mut globalconfig = GlobalConfig::try_from(globalconfig_account)?; + let (globalconfig_pda, _) = get_globalconfig_pda(program_id); assert_eq!( globalconfig_account.key, &globalconfig_pda, "Invalid GlobalConfig PubKey" @@ -107,16 +112,10 @@ pub fn process_update_exchange( } if let Some(_bgp_community) = value.bgp_community { exchange.bgp_community = assign_bgp_community(&mut globalconfig); - globalconfig_write_with_realloc( - globalconfig_account, - &globalconfig, - payer_account, - system_program, - globalconfig_bump_seed, - ); + try_acc_write(&globalconfig, globalconfig_account, payer_account, accounts)?; } - account_write(exchange_account, &exchange, payer_account, system_program)?; + try_acc_write(&exchange, exchange_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", exchange); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/globalconfig/set.rs b/smartcontract/programs/doublezero-serviceability/src/processors/globalconfig/set.rs index 74583f7ce..0a82fab41 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/globalconfig/set.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/globalconfig/set.rs @@ -1,9 +1,12 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalconfig_write_with_realloc, globalstate_get}, pda::*, seeds::{SEED_CONFIG, SEED_PREFIX}, - state::{accounttype::AccountType, exchange::BGP_COMMUNITY_MIN, globalconfig::GlobalConfig}, + serializer::try_acc_write, + state::{ + accounttype::AccountType, exchange::BGP_COMMUNITY_MIN, globalconfig::GlobalConfig, + globalstate::GlobalState, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -52,7 +55,7 @@ pub fn process_set_globalconfig( let pda_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_set_global_config({:?})", value); @@ -66,7 +69,7 @@ pub fn process_set_globalconfig( "Invalid GlobalState Account Owner" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -114,13 +117,7 @@ pub fn process_set_globalconfig( let mut account_data = &mut pda_account.data.borrow_mut()[..]; data.serialize(&mut account_data).unwrap(); } else { - globalconfig_write_with_realloc( - pda_account, - &data, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&data, pda_account, payer_account, accounts)?; } #[cfg(test)] diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/initialize.rs b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/initialize.rs index 3547b74d4..4a5f086a3 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/initialize.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/initialize.rs @@ -1,14 +1,10 @@ -use std::str::FromStr; - use crate::{ - accounts::write_account, pda::*, programversion::ProgramVersion, - seeds::{SEED_GLOBALSTATE, SEED_PREFIX}, + seeds::{SEED_GLOBALSTATE, SEED_PREFIX, SEED_PROGRAM_CONFIG}, + serializer::{try_acc_create, try_acc_write}, state::{accounttype::AccountType, globalstate::GlobalState, programconfig::ProgramConfig}, }; -use borsh::BorshSerialize; -use doublezero_program_common::create_account::try_create_account; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -16,20 +12,34 @@ use solana_program::{ entrypoint::ProgramResult, pubkey::Pubkey, }; +use std::str::FromStr; pub fn initialize_global_state(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let accounts_iter = &mut accounts.iter(); let program_config_account = next_account_info(accounts_iter)?; - let pda_account = next_account_info(accounts_iter)?; + let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let system_account = next_account_info(accounts_iter)?; #[cfg(test)] msg!("initialize_global_state()"); + assert!( + program_config_account.is_writable, + "ProgramConfig must be writable" + ); + assert!( + globalstate_account.is_writable, + "GlobalState must be writable" + ); // Check if the payer is a signer assert!(payer_account.is_signer, "Payer must be a signer"); + assert_eq!( + system_account.key, + &solana_program::system_program::id(), + "Invalid System Program account" + ); let (program_config_pda, program_config_bump_seed) = get_program_config_pda(program_id); assert_eq!( @@ -37,36 +47,52 @@ pub fn initialize_global_state(program_id: &Pubkey, accounts: &[AccountInfo]) -> "Invalid ProgramConfig PubKey" ); - // Initialize or update the ProgramConfig account - write_account( - program_config_account, - &ProgramConfig { - account_type: AccountType::ProgramConfig, - bump_seed: program_config_bump_seed, // This is not used in this context - version: ProgramVersion::current(), // Default version for initialization - min_compatible_version: ProgramVersion::from_str( - crate::min_version::MIN_COMPATIBLE_VERSION, - ) - .unwrap(), - }, - program_id, - payer_account, - system_program, - )?; + let program_config = ProgramConfig { + account_type: AccountType::ProgramConfig, + bump_seed: program_config_bump_seed, // This is not used in this context + version: ProgramVersion::current(), // Default version for initialization + min_compatible_version: ProgramVersion::from_str( + crate::min_version::MIN_COMPATIBLE_VERSION, + ) + .unwrap(), + }; + + // Create the ProgramConfig account if it doesn't exist + if program_config_account.data_is_empty() { + try_acc_create( + &program_config, + program_config_account, + payer_account, + system_account, + program_id, + &[ + SEED_PREFIX, + SEED_PROGRAM_CONFIG, + &[program_config_bump_seed], + ], + )?; + } else { + try_acc_write( + &program_config, + program_config_account, + payer_account, + accounts, + )?; + } - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_globalstate_account, bump_seed) = get_globalstate_pda(program_id); assert_eq!( - pda_account.key, &expected_pda_account, + globalstate_account.key, &expected_globalstate_account, "Invalid GlobalState PubKey" ); // Check if the account is already initialized - if !pda_account.data.borrow().is_empty() { + if !globalstate_account.data_is_empty() { return Ok(()); } // Create the GlobalState account - let data = GlobalState { + let globalstate = GlobalState { account_type: AccountType::GlobalState, bump_seed, account_index: 0, @@ -79,25 +105,17 @@ pub fn initialize_global_state(program_id: &Pubkey, accounts: &[AccountInfo]) -> user_airdrop_lamports: 40_000, }; - // Size of our index account - let account_space = data.size(); - // At this point, the account data is guaranteed to be empty due to the earlier check. - // Create the index account - try_create_account( - payer_account.key, // Account paying for the new account - pda_account.key, // Account to be created - pda_account.lamports(), // Current amount of lamports on the new account - account_space, // Size in bytes to allocate for the data field - program_id, // Set program owner to our program - accounts, + try_acc_create( + &globalstate, + globalstate_account, + payer_account, + system_account, + program_id, &[SEED_PREFIX, SEED_GLOBALSTATE, &[bump_seed]], )?; - let mut account_data = &mut pda_account.data.borrow_mut()[..]; - data.serialize(&mut account_data).unwrap(); - #[cfg(test)] - msg!("{:?}", account_data); + msg!("{:?}", globalstate); Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setairdrop.rs b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setairdrop.rs index cd51d9710..b4c87a0f3 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setairdrop.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setairdrop.rs @@ -1,7 +1,6 @@ use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::get_globalstate_pda, + error::DoubleZeroError, pda::get_globalstate_pda, serializer::try_acc_write, + state::globalstate::GlobalState, }; use borsh::BorshSerialize; @@ -59,14 +58,14 @@ pub fn process_set_airdrop( "Invalid System Program Account Owner" ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( globalstate_account.key, &expected_pda_account, "Invalid GlobalState Pubkey", ); // Fetch the globalstate and ensure payer authorization to adjust airdrop - let mut globalstate = globalstate_get(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -79,13 +78,7 @@ pub fn process_set_airdrop( globalstate.user_airdrop_lamports = user_airdrop_lamports; } - globalstate_write_with_realloc( - globalstate_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setauthority.rs b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setauthority.rs index 36e7c330d..af58cf443 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setauthority.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setauthority.rs @@ -1,12 +1,9 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, - globalstate::{globalstate_get, globalstate_write_with_realloc}, - pda::*, + error::DoubleZeroError, pda::*, serializer::try_acc_write, state::globalstate::GlobalState, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -64,14 +61,14 @@ pub fn process_set_authority( "PDA Account is not writable" ); - let (expected_pda_account, bump_seed) = get_globalstate_pda(program_id); + let (expected_pda_account, _) = get_globalstate_pda(program_id); assert_eq!( globalstate_account.key, &expected_pda_account, "Invalid GlobalState PubKey" ); // Parse the global state account & check if the payer is in the allowlist - let mut globalstate = globalstate_get(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -84,13 +81,8 @@ pub fn process_set_authority( globalstate.sentinel_authority_pk = sentinel_authority_pk; } - globalstate_write_with_realloc( - globalstate_account, - &globalstate, - payer_account, - system_program, - bump_seed, - ); + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setversion.rs b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setversion.rs index a547ad725..d71a27040 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setversion.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/globalstate/setversion.rs @@ -1,12 +1,13 @@ -use core::fmt; - use crate::{ - accounts::AccountSize, error::DoubleZeroError, globalstate::globalstate_get, pda::*, - programversion::ProgramVersion, state::programconfig::ProgramConfig, + error::DoubleZeroError, + pda::*, + programversion::ProgramVersion, + serializer::try_acc_write, + state::{globalstate::GlobalState, programconfig::ProgramConfig}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; -use doublezero_program_common::resize_account::resize_account_if_needed; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -75,7 +76,7 @@ pub fn process_set_version( ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -88,13 +89,12 @@ pub fn process_set_version( program_config.min_compatible_version = value.min_compatible_version.clone(); - resize_account_if_needed( + try_acc_write( + &program_config, program_config_account, payer_account, accounts, - program_config.size(), )?; - program_config.try_serialize(program_config_account)?; #[cfg(test)] msg!("Updated: {:?}", globalstate); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/accept.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/accept.rs index bc27c93f9..d870b5783 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/accept.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/accept.rs @@ -1,12 +1,11 @@ -use core::fmt; - use crate::{ error::DoubleZeroError, - helper::*, + serializer::try_acc_write, state::{contributor::Contributor, device::Device, link::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -38,7 +37,7 @@ pub fn process_accept_link( let side_z_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_accept_link({:?})", value); @@ -94,7 +93,7 @@ pub fn process_accept_link( link.side_z_iface_name = value.side_z_iface_name.clone(); link.status = LinkStatus::Pending; - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&link, link_account, payer_account, accounts)?; #[cfg(test)] msg!("Accepted: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/activate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/activate.rs index 0fb812479..a0ebd9cc5 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/activate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/activate.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::*, interface::InterfaceStatus, link::*}, + serializer::try_acc_write, + state::{device::*, globalstate::GlobalState, interface::InterfaceStatus, link::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -44,7 +43,7 @@ pub fn process_activate_link( let side_z_device_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_activate_link({:?})", value); @@ -77,7 +76,7 @@ pub fn process_activate_link( "Side Z PDA Account is not writable" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -120,19 +119,9 @@ pub fn process_activate_link( link.tunnel_net = value.tunnel_net; link.status = LinkStatus::Activated; - account_write( - side_a_device_account, - &side_a_dev, - payer_account, - system_program, - )?; - account_write( - side_z_device_account, - &side_z_dev, - payer_account, - system_program, - )?; - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&side_a_dev, side_a_device_account, payer_account, accounts)?; + try_acc_write(&side_z_dev, side_z_device_account, payer_account, accounts)?; + try_acc_write(&link, link_account, payer_account, accounts)?; #[cfg(test)] msg!("Activated: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/closeaccount.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/closeaccount.rs index f88bc5e1a..1792792bb 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/closeaccount.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/closeaccount.rs @@ -1,8 +1,10 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{contributor::Contributor, device::*, interface::InterfaceStatus, link::*}, + serializer::{try_acc_close, try_acc_write}, + state::{ + contributor::Contributor, device::*, globalstate::GlobalState, interface::InterfaceStatus, + link::*, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -74,7 +76,7 @@ pub fn process_closeaccount_link( // Check if the account is writable assert!(link_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -111,15 +113,10 @@ pub fn process_closeaccount_link( side_a_dev.reference_count = side_a_dev.reference_count.saturating_sub(1); side_z_dev.reference_count = side_z_dev.reference_count.saturating_sub(1); - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; - account_write(side_a_account, &side_a_dev, payer_account, system_program)?; - account_write(side_z_account, &side_z_dev, payer_account, system_program)?; - account_close(link_account, owner_account)?; + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; + try_acc_write(&side_a_dev, side_a_account, payer_account, accounts)?; + try_acc_write(&side_z_dev, side_z_account, payer_account, accounts)?; + try_acc_close(link_account, owner_account)?; #[cfg(test)] msg!("CloseAccount: Link closed"); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/create.rs index 25d1b8842..a860694aa 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/create.rs @@ -1,9 +1,12 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::*, pda::get_link_pda, - state::{accounttype::AccountType, contributor::Contributor, device::Device, link::*}, + seeds::{SEED_LINK, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, + state::{ + accounttype::AccountType, contributor::Contributor, device::Device, + globalstate::GlobalState, link::*, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -81,12 +84,19 @@ pub fn process_create_link( globalstate_account.owner, program_id, "Invalid GlobalState Account Owner" ); + assert_eq!( + *system_program.unsigned_key(), + solana_program::system_program::id(), + "Invalid System Program Account Owner" + ); - if !link_account.data.borrow().is_empty() { + if !link_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; + let mut contributor = Contributor::try_from(contributor_account)?; if contributor.owner != *payer_account.key @@ -172,22 +182,23 @@ pub fn process_create_link( delay_override_ns: 0, }; - account_create( - link_account, + try_acc_create( &tunnel, + link_account, payer_account, system_program, program_id, + &[ + SEED_PREFIX, + SEED_LINK, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], )?; - account_write( - contributor_account, - &contributor, - payer_account, - system_program, - )?; - account_write(side_a_account, &side_a_dev, payer_account, system_program)?; - account_write(side_z_account, &side_z_dev, payer_account, system_program)?; - globalstate_write(globalstate_account, &globalstate)?; + try_acc_write(&contributor, contributor_account, payer_account, accounts)?; + try_acc_write(&side_a_dev, side_a_account, payer_account, accounts)?; + try_acc_write(&side_z_dev, side_z_account, payer_account, accounts)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/delete.rs index 5fdefeaee..881dbc45e 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/delete.rs @@ -1,8 +1,9 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountType, contributor::Contributor, link::*}, + serializer::try_acc_write, + state::{ + accounttype::AccountType, contributor::Contributor, globalstate::GlobalState, link::*, + }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -60,7 +61,7 @@ pub fn process_delete_link( "Invalid System Program Account Owner" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; assert_eq!(globalstate.account_type, AccountType::GlobalState); let contributor = Contributor::try_from(contributor_account)?; @@ -75,7 +76,7 @@ pub fn process_delete_link( let mut link: Link = Link::try_from(link_account)?; link.status = LinkStatus::Deleting; - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&link, link_account, payer_account, accounts)?; #[cfg(test)] msg!("Deleting: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/reject.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/reject.rs index c692fafce..ba74c97a9 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/reject.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/reject.rs @@ -1,4 +1,8 @@ -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::link::*}; +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, link::*}, +}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use doublezero_program_common::types::NetworkV4; @@ -52,7 +56,7 @@ pub fn process_reject_link( ); assert!(link_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -68,7 +72,7 @@ pub fn process_reject_link( link.status = LinkStatus::Rejected; msg!("Reason: {:?}", value.reason); - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&link, link_account, payer_account, accounts)?; #[cfg(test)] msg!("Rejectd: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/resume.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/resume.rs index be19be599..51f161579 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/resume.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/resume.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{contributor::Contributor, link::*}, + serializer::try_acc_write, + state::{contributor::Contributor, globalstate::GlobalState, link::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -60,7 +59,7 @@ pub fn process_resume_link( "Invalid System Program Account Owner" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; let contributor = Contributor::try_from(contributor_account)?; if contributor.owner != *payer_account.key @@ -77,7 +76,7 @@ pub fn process_resume_link( link.status = LinkStatus::Activated; - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&link, link_account, payer_account, accounts)?; #[cfg(test)] msg!("Resumed: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/suspend.rs index 70c7d04b0..72e2f45e1 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/suspend.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{contributor::Contributor, link::*}, + serializer::try_acc_write, + state::{contributor::Contributor, globalstate::GlobalState, link::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -60,7 +59,7 @@ pub fn process_suspend_link( // Check if the account is writable assert!(link_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; let contributor = Contributor::try_from(contributor_account)?; if contributor.owner != *payer_account.key @@ -79,7 +78,7 @@ pub fn process_suspend_link( link.status = LinkStatus::Suspended; - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&link, link_account, payer_account, accounts)?; msg!("Suspended: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/link/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/link/update.rs index cd0bf207a..dcc8f3334 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/link/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/link/update.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{contributor::Contributor, device::Device, link::*}, + serializer::try_acc_write, + state::{contributor::Contributor, device::Device, globalstate::GlobalState, link::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -104,7 +103,7 @@ pub fn process_update_link( // Check if the account is writable assert!(link_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; let contributor = Contributor::try_from(contributor_account)?; if contributor.owner != *payer_account.key @@ -194,7 +193,7 @@ pub fn process_update_link( } } - account_write(link_account, &link, payer_account, system_program)?; + try_acc_write(&link, link_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", link); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/location/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/location/create.rs index 3621bb08f..1d3f217cc 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/location/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/location/create.rs @@ -1,9 +1,9 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::*, pda::*, - state::{accounttype::AccountType, location::*}, + seeds::{SEED_LOCATION, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, + state::{accounttype::AccountType, globalstate::GlobalState, location::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -84,7 +84,9 @@ pub fn process_create_location( assert!(location_account.is_writable, "PDA Account is not writable"); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; + if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -96,7 +98,7 @@ pub fn process_create_location( ); // Check if the account is already initialized - if !location_account.data.borrow().is_empty() { + if !location_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } @@ -115,14 +117,20 @@ pub fn process_create_location( status: LocationStatus::Activated, }; - account_create( - location_account, + try_acc_create( &location, + location_account, payer_account, system_program, program_id, + &[ + SEED_PREFIX, + SEED_LOCATION, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], )?; - globalstate_write(globalstate_account, &globalstate)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/location/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/location/delete.rs index 4aa3ccf18..1fcfc64ac 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/location/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/location/delete.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountType, location::*}, + serializer::try_acc_close, + state::{accounttype::AccountType, globalstate::GlobalState, location::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -59,7 +58,7 @@ pub fn process_delete_location( assert!(location_account.is_writable, "PDA Account is not writable"); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -77,7 +76,7 @@ pub fn process_delete_location( return Err(DoubleZeroError::ReferenceCountNotZero.into()); } - account_close(location_account, payer_account)?; + try_acc_close(location_account, payer_account)?; #[cfg(test)] msg!("Deleted: {:?}", location_account); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/location/resume.rs b/smartcontract/programs/doublezero-serviceability/src/processors/location/resume.rs index f9a80e1e6..06fe50bba 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/location/resume.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/location/resume.rs @@ -1,8 +1,11 @@ -use core::fmt; - -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::location::*}; +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, location::*}, +}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -54,7 +57,7 @@ pub fn process_resume_location( assert!(location_account.is_writable, "PDA Account is not writable"); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -62,7 +65,7 @@ pub fn process_resume_location( let mut location: Location = Location::try_from(location_account)?; location.status = LocationStatus::Activated; - account_write(location_account, &location, payer_account, system_program)?; + try_acc_write(&location, location_account, payer_account, accounts)?; #[cfg(test)] msg!("Resumed: {:?}", location); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/location/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/location/suspend.rs index 1f2e91924..c76e6b7c4 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/location/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/location/suspend.rs @@ -1,8 +1,11 @@ -use core::fmt; - -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::location::*}; +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, location::*}, +}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -55,7 +58,7 @@ pub fn process_suspend_location( assert!(location_account.is_writable, "PDA Account is not writable"); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -64,7 +67,7 @@ pub fn process_suspend_location( location.status = LocationStatus::Suspended; - account_write(location_account, &location, payer_account, system_program)?; + try_acc_write(&location, location_account, payer_account, accounts)?; #[cfg(test)] msg!("Suspended: {:?}", location); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/location/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/location/update.rs index 0214d5564..c774acd66 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/location/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/location/update.rs @@ -1,4 +1,8 @@ -use crate::{error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::location::*}; +use crate::{ + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, location::*}, +}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use doublezero_program_common::validate_account_code; @@ -64,7 +68,7 @@ pub fn process_update_location( ); assert!(location_account.is_writable, "PDA Account is not writable"); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -92,7 +96,7 @@ pub fn process_update_location( location.loc_id = loc_id; } - account_write(location_account, &location, payer_account, system_program)?; + try_acc_write(&location, location_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", location); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/migrate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/migrate.rs index 0ceaa00fb..c54bf2be6 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/migrate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/migrate.rs @@ -1,15 +1,13 @@ -use core::fmt; - use crate::{ - accounts::account_close, error::DoubleZeroError, - helper::account_create_with_seed, pda::get_user_pda, seeds::{SEED_PREFIX, SEED_USER}, + serializer::{try_acc_close, try_acc_create}, state::{accounttype::AccountType, user::User}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -84,9 +82,9 @@ pub fn process_migrate( actual_user.index = 0; // Reset index for new account actual_user.bump_seed = bump_seed; // Create new account with the same data - account_create_with_seed( - new_account, + try_acc_create( &actual_user, + new_account, payer_account, system_program, program_id, @@ -102,7 +100,7 @@ pub fn process_migrate( msg!("{:?}", actual_user); // Close actual account - account_close(actual_account, payer_account)?; + try_acc_close(actual_account, payer_account)?; } else { return Err(DoubleZeroError::InvalidAccountType.into()); } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/activate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/activate.rs index a51b162aa..891f9d9d7 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/activate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/activate.rs @@ -1,5 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -33,7 +35,7 @@ pub fn process_activate_multicastgroup( let multicastgroup_account = next_account_info(accounts_iter)?; let globalstate_account = next_account_info(accounts_iter)?; let payer_account = next_account_info(accounts_iter)?; - let system_program = next_account_info(accounts_iter)?; + let _system_program = next_account_info(accounts_iter)?; #[cfg(test)] msg!("process_activate_multicastgroup({:?})", value); @@ -56,7 +58,7 @@ pub fn process_activate_multicastgroup( "PDA Account is not writable" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -70,11 +72,11 @@ pub fn process_activate_multicastgroup( multicastgroup.multicast_ip = value.multicast_ip; multicastgroup.status = MulticastGroupStatus::Activated; - account_write( - multicastgroup_account, + try_acc_write( &multicastgroup, + multicastgroup_account, payer_account, - system_program, + accounts, )?; msg!("Activated: {:?}", multicastgroup); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/add.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/add.rs index 8ba79c164..ff10dc70b 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/add.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/add.rs @@ -1,18 +1,18 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, pda::get_accesspass_pda, seeds::{SEED_ACCESS_PASS, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, state::{ accesspass::{AccessPass, AccessPassStatus, AccessPassType}, - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, + globalstate::GlobalState, multicastgroup::MulticastGroup, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::{resize_account::resize_account_if_needed, try_create_account}; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -73,7 +73,7 @@ pub fn process_add_multicastgroup_pub_allowlist( // Parse the global state account let mgroup = MulticastGroup::try_from(mgroup_account)?; - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; // Check whether mgroup is authorized let is_authorized = (mgroup.owner == *payer_account.key) @@ -104,13 +104,12 @@ pub fn process_add_multicastgroup_pub_allowlist( flags: 0, }; - try_create_account( - payer_account.key, // Account paying for the new account - accesspass_account.key, // Account to be created - accesspass_account.lamports(), // Current amount of lamports on the new account - accesspass.size(), // Size in bytes to allocate for the data field - program_id, // Set program owner to our program - accounts, + try_acc_create( + &accesspass, + accesspass_account, + payer_account, + system_program, + program_id, &[ SEED_PREFIX, SEED_ACCESS_PASS, @@ -119,7 +118,6 @@ pub fn process_add_multicastgroup_pub_allowlist( &[bump_seed], ], )?; - accesspass.try_serialize(accesspass_account)?; } else { assert_eq!( accesspass_account.owner, program_id, @@ -140,13 +138,7 @@ pub fn process_add_multicastgroup_pub_allowlist( accesspass.mgroup_pub_allowlist.push(*mgroup_account.key); } - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; } #[cfg(test)] diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/remove.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/remove.rs index 157508d3a..dfc5e5277 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/remove.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/remove.rs @@ -1,12 +1,12 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - state::{accesspass::AccessPass, accounttype::AccountTypeInfo, multicastgroup::MulticastGroup}, + serializer::try_acc_write, + state::{accesspass::AccessPass, globalstate::GlobalState, multicastgroup::MulticastGroup}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -74,7 +74,7 @@ pub fn process_remove_multicast_pub_allowlist( // Parse the global state account let mgroup = MulticastGroup::try_from(mgroup_account)?; - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; // Check whether mgroup is authorized let is_authorized = (mgroup.owner == *payer_account.key) @@ -97,13 +97,7 @@ pub fn process_remove_multicast_pub_allowlist( .mgroup_pub_allowlist .retain(|x| x != mgroup_account.key); - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", mgroup); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs index 35c38aa8e..df8c30e8b 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs @@ -1,18 +1,19 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, pda::get_accesspass_pda, seeds::{SEED_ACCESS_PASS, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, state::{ accesspass::{AccessPass, AccessPassStatus, AccessPassType}, - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, + globalstate::GlobalState, multicastgroup::MulticastGroup, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::{resize_account::resize_account_if_needed, try_create_account}; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -73,7 +74,7 @@ pub fn process_add_multicastgroup_sub_allowlist( // Parse the global state account let mgroup = MulticastGroup::try_from(mgroup_account)?; - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; // Check whether mgroup is authorized let is_authorized = (mgroup.owner == *payer_account.key) @@ -104,13 +105,12 @@ pub fn process_add_multicastgroup_sub_allowlist( flags: 0, }; - try_create_account( - payer_account.key, // Account paying for the new account - accesspass_account.key, // Account to be created - accesspass_account.lamports(), // Current amount of lamports on the new account - accesspass.size(), // Size in bytes to allocate for the data field - program_id, // Set program owner to our program - accounts, + try_acc_create( + &accesspass, + accesspass_account, + payer_account, + system_program, + program_id, &[ SEED_PREFIX, SEED_ACCESS_PASS, @@ -119,7 +119,6 @@ pub fn process_add_multicastgroup_sub_allowlist( &[bump_seed], ], )?; - accesspass.try_serialize(accesspass_account)?; } else { assert_eq!( accesspass_account.owner, program_id, @@ -140,13 +139,7 @@ pub fn process_add_multicastgroup_sub_allowlist( accesspass.mgroup_sub_allowlist.push(*mgroup_account.key); } - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; } #[cfg(test)] diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/remove.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/remove.rs index ed94e2331..55d549bea 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/remove.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/remove.rs @@ -1,12 +1,12 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - state::{accesspass::AccessPass, accounttype::AccountTypeInfo, multicastgroup::MulticastGroup}, + serializer::try_acc_write, + state::{accesspass::AccessPass, globalstate::GlobalState, multicastgroup::MulticastGroup}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -74,7 +74,7 @@ pub fn process_remove_multicast_sub_allowlist( // Parse the global state account let mgroup = MulticastGroup::try_from(mgroup_account)?; - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; // Check whether mgroup is authorized let is_authorized = (mgroup.owner == *payer_account.key) @@ -97,13 +97,7 @@ pub fn process_remove_multicast_sub_allowlist( .mgroup_sub_allowlist .retain(|x| x != mgroup_account.key); - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", mgroup); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/closeaccount.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/closeaccount.rs index 94b7340d4..a0829e9fa 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/closeaccount.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/closeaccount.rs @@ -1,5 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_close, + state::{globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -22,7 +24,7 @@ impl fmt::Debug for MulticastGroupDeactivateArgs { } } -pub fn process_deactivate_multicastgroup( +pub fn process_closeaccount_multicastgroup( program_id: &Pubkey, accounts: &[AccountInfo], _value: &MulticastGroupDeactivateArgs, @@ -61,7 +63,7 @@ pub fn process_deactivate_multicastgroup( "PDA Account is not writable" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -77,7 +79,7 @@ pub fn process_deactivate_multicastgroup( return Err(solana_program::program_error::ProgramError::Custom(1)); } - account_close(multicastgroup_account, owner_account)?; + try_acc_close(multicastgroup_account, owner_account)?; #[cfg(test)] msg!("Deactivated: MulticastGroup closed"); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/create.rs index 5669ab68b..c1275ef01 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/create.rs @@ -1,9 +1,9 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::*, pda::get_multicastgroup_pda, - state::{accounttype::AccountType, multicastgroup::*}, + seeds::{SEED_MULTICAST_GROUP, SEED_PREFIX}, + serializer::{try_acc_create, try_acc_write}, + state::{accounttype::AccountType, globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -83,13 +83,15 @@ pub fn process_create_multicastgroup( "Invalid MulticastGroup Bump Seed" ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; + if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } // Check if the account is already initialized - if !mgroup_account.data.borrow().is_empty() { + if !mgroup_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } @@ -107,14 +109,20 @@ pub fn process_create_multicastgroup( subscriber_count: 0, }; - account_create( - mgroup_account, + try_acc_create( &multicastgroup, + mgroup_account, payer_account, system_program, program_id, + &[ + SEED_PREFIX, + SEED_MULTICAST_GROUP, + &globalstate.account_index.to_le_bytes(), + &[bump_seed], + ], )?; - globalstate_write(globalstate_account, &globalstate)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/delete.rs index 09ba6e29d..6e4f8e9a2 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/delete.rs @@ -1,10 +1,11 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -60,7 +61,7 @@ pub fn process_delete_multicastgroup( ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -72,11 +73,11 @@ pub fn process_delete_multicastgroup( } multicastgroup.status = MulticastGroupStatus::Deleting; - account_write( - multicastgroup_account, + try_acc_write( &multicastgroup, + multicastgroup_account, payer_account, - system_program, + accounts, )?; #[cfg(test)] diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reactivate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reactivate.rs index 8d8fd4109..980e86f63 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reactivate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reactivate.rs @@ -1,10 +1,11 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -59,7 +60,7 @@ pub fn process_reactivate_multicastgroup( ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -67,15 +68,15 @@ pub fn process_reactivate_multicastgroup( let mut multicastgroup: MulticastGroup = MulticastGroup::try_from(multicastgroup_account)?; multicastgroup.status = MulticastGroupStatus::Activated; - account_write( - multicastgroup_account, + try_acc_write( &multicastgroup, + multicastgroup_account, payer_account, - system_program, + accounts, )?; #[cfg(test)] - msg!("Suspended: {:?}", multicastgroup); + msg!("Reactivated: {:?}", multicastgroup); Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reject.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reject.rs index ed2eb1f2c..f7a07fd23 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reject.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/reject.rs @@ -1,5 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, multicastgroup::*}, }; use std::fmt; @@ -60,7 +62,7 @@ pub fn process_reject_multicastgroup( "PDA Account is not writable" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -74,11 +76,11 @@ pub fn process_reject_multicastgroup( multicastgroup.status = MulticastGroupStatus::Rejected; msg!("Reason: {:?}", value.reason); - account_write( - multicastgroup_account, + try_acc_write( &multicastgroup, + multicastgroup_account, payer_account, - system_program, + accounts, )?; #[cfg(test)] diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs index 3f82d491f..6849c69de 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs @@ -1,17 +1,15 @@ use crate::{ error::DoubleZeroError, - helper::account_write, pda::get_accesspass_pda, + serializer::try_acc_write, state::{ accesspass::AccessPass, - accounttype::AccountTypeInfo, multicastgroup::{MulticastGroup, MulticastGroupStatus}, user::{User, UserStatus}, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; -use doublezero_program_common::resize_account::resize_account_if_needed; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -170,9 +168,8 @@ pub fn process_subscribe_multicastgroup( } } - account_write(mgroup_account, &mgroup, payer_account, system_program)?; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&mgroup, mgroup_account, payer_account, accounts)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Updated: {:?}", mgroup); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/suspend.rs index dd0ce9592..27dcd241c 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/suspend.rs @@ -1,10 +1,11 @@ -use core::fmt; - use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; +use core::fmt; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -60,7 +61,7 @@ pub fn process_suspend_multicastgroup( ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -68,11 +69,11 @@ pub fn process_suspend_multicastgroup( let mut multicastgroup: MulticastGroup = MulticastGroup::try_from(multicastgroup_account)?; multicastgroup.status = MulticastGroupStatus::Suspended; - account_write( - multicastgroup_account, + try_acc_write( &multicastgroup, + multicastgroup_account, payer_account, - system_program, + accounts, )?; #[cfg(test)] diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/update.rs index f92f3e268..bae9af5fb 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/update.rs @@ -1,5 +1,7 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, helper::*, state::multicastgroup::*, + error::DoubleZeroError, + serializer::try_acc_write, + state::{globalstate::GlobalState, multicastgroup::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -68,7 +70,7 @@ pub fn process_update_multicastgroup( "PDA Account is not writable" ); // Parse the global state account & check if the payer is in the allowlist - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -93,11 +95,11 @@ pub fn process_update_multicastgroup( multicastgroup.subscriber_count = *subscriber_count; } - account_write( - multicastgroup_account, + try_acc_write( &multicastgroup, + multicastgroup_account, payer_account, - system_program, + accounts, )?; msg!("Updated: {:?}", multicastgroup); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/resource/allocate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/resource/allocate.rs index 74c7d1bf7..08e28a9da 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/resource/allocate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/resource/allocate.rs @@ -1,6 +1,8 @@ use crate::{ - error::DoubleZeroError, globalstate::globalstate_get, pda::get_resource_extension_pda, - resource::IdOrIp, state::resource_extension::ResourceExtensionBorrowed, + error::DoubleZeroError, + pda::get_resource_extension_pda, + resource::IdOrIp, + state::{globalstate::GlobalState, resource_extension::ResourceExtensionBorrowed}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -65,7 +67,7 @@ pub fn process_allocate_resource( // Check if the account is writable assert!(resource_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/resource/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/resource/create.rs index 6e38aa507..608bd4b28 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/resource/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/resource/create.rs @@ -1,4 +1,4 @@ -use crate::{error::DoubleZeroError, globalstate::globalstate_get}; +use crate::{error::DoubleZeroError, state::globalstate::GlobalState}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; #[cfg(test)] @@ -60,7 +60,7 @@ pub fn process_create_resource( "Invalid System Program Account Owner" ); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/resource/deallocate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/resource/deallocate.rs index 7f6282237..af6186506 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/resource/deallocate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/resource/deallocate.rs @@ -1,9 +1,8 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, pda::get_resource_extension_pda, resource::{IdOrIp, ResourceType}, - state::resource_extension::ResourceExtensionBorrowed, + state::{globalstate::GlobalState, resource_extension::ResourceExtensionBorrowed}, }; use borsh::{BorshDeserialize, BorshSerialize}; #[cfg(test)] @@ -76,7 +75,7 @@ pub fn process_deallocate_resource( // Check if the account is writable assert!(resource_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/activate.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/activate.rs index 07be6ea8d..a1f3c9c88 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/activate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/activate.rs @@ -1,16 +1,16 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, + serializer::try_acc_write, state::{ accesspass::AccessPass, - accounttype::AccountTypeInfo, + globalstate::GlobalState, user::{User, UserStatus}, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::{resize_account::resize_account_if_needed, types::NetworkV4}; +use doublezero_program_common::types::NetworkV4; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -77,7 +77,7 @@ pub fn process_activate_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -103,15 +103,8 @@ pub fn process_activate_user( user.dz_ip = value.dz_ip; user.try_activate(&mut accesspass)?; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; #[cfg(test)] msg!("Activated: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/ban.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/ban.rs index 5038b9d87..4c194a5d3 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/ban.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/ban.rs @@ -1,12 +1,11 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - state::{accounttype::AccountTypeInfo, user::*}, + serializer::try_acc_write, + state::{globalstate::GlobalState, user::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -56,7 +55,7 @@ pub fn process_ban_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -64,8 +63,7 @@ pub fn process_ban_user( let mut user: User = User::try_from(user_account)?; user.status = UserStatus::Banned; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Banned: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/check_access_pass.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/check_access_pass.rs index e923f3ef2..46ada353e 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/check_access_pass.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/check_access_pass.rs @@ -1,17 +1,17 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, pda::get_accesspass_pda, + serializer::try_acc_write, state::{ accesspass::{AccessPass, AccessPassStatus}, - accounttype::AccountTypeInfo, + globalstate::GlobalState, user::{User, UserStatus}, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -69,7 +69,7 @@ pub fn process_check_access_pass_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -102,15 +102,8 @@ pub fn process_check_access_pass_user( UserStatus::Activated }; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; #[cfg(test)] msg!("OutOfCredits: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/closeaccount.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/closeaccount.rs index c552fc347..c260c045d 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/closeaccount.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/closeaccount.rs @@ -1,8 +1,7 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - helper::*, - state::{device::Device, user::*}, + serializer::{try_acc_close, try_acc_write}, + state::{device::Device, globalstate::GlobalState, user::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; @@ -62,7 +61,7 @@ pub fn process_closeaccount_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if globalstate.activator_authority_pk != *payer_account.key { return Err(DoubleZeroError::NotAllowed.into()); } @@ -82,8 +81,8 @@ pub fn process_closeaccount_user( device.reference_count = device.reference_count.saturating_sub(1); device.users_count = device.users_count.saturating_sub(1); - account_write(device_account, &device, payer_account, system_program)?; - account_close(user_account, owner_account)?; + try_acc_write(&device, device_account, payer_account, accounts)?; + try_acc_close(user_account, owner_account)?; #[cfg(test)] msg!("CloseAccount: User closed"); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/create.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/create.rs index ce49bfbc9..415f9e5a4 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/create.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/create.rs @@ -1,20 +1,20 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::*, pda::{get_accesspass_pda, get_user_old_pda, get_user_pda}, seeds::{SEED_PREFIX, SEED_USER}, + serializer::{try_acc_create, try_acc_write}, state::{ accesspass::{AccessPass, AccessPassStatus, AccessPassType}, - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, device::{Device, DeviceStatus}, + globalstate::GlobalState, user::*, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::{resize_account::resize_account_if_needed, types::NetworkV4}; +use doublezero_program_common::types::NetworkV4; use solana_program::{ account_info::{next_account_info, AccountInfo}, clock::Clock, @@ -69,7 +69,7 @@ pub fn process_create_user( // Check if the payer is a signer assert!(payer_account.is_signer, "Payer must be a signer"); - if !user_account.data.borrow().is_empty() { + if !user_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } if accesspass_account.data_is_empty() { @@ -80,7 +80,8 @@ pub fn process_create_user( "Invalid AccessPass Account Owner" ); - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; let (expected_old_pda_account, bump_old_seed) = get_user_old_pda(program_id, globalstate.account_index); @@ -212,9 +213,9 @@ pub fn process_create_user( }; if pda_ver == PDAVersion::V1 { - account_create_with_seed( - user_account, + try_acc_create( &user, + user_account, payer_account, system_program, program_id, @@ -225,11 +226,11 @@ pub fn process_create_user( &[bump_old_seed], ], )?; - globalstate_write(globalstate_account, &globalstate)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; } else { - account_create_with_seed( - user_account, + try_acc_create( &user, + user_account, payer_account, system_program, program_id, @@ -243,14 +244,8 @@ pub fn process_create_user( )? } - account_write(device_account, &device, payer_account, system_program)?; - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&device, device_account, payer_account, accounts)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs index d248ad345..c0a0d4083 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs @@ -1,13 +1,13 @@ use crate::{ error::DoubleZeroError, - globalstate::{globalstate_get_next, globalstate_write}, - helper::*, pda::{get_accesspass_pda, get_user_old_pda, get_user_pda}, seeds::{SEED_PREFIX, SEED_USER}, + serializer::{try_acc_create, try_acc_write}, state::{ accesspass::{AccessPass, AccessPassStatus, AccessPassType}, - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, device::{Device, DeviceStatus}, + globalstate::GlobalState, multicastgroup::{MulticastGroup, MulticastGroupStatus}, user::*, }, @@ -15,7 +15,7 @@ use crate::{ use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::{resize_account::resize_account_if_needed, types::NetworkV4}; +use doublezero_program_common::types::NetworkV4; use solana_program::{ account_info::{next_account_info, AccountInfo}, clock::Clock, @@ -74,7 +74,7 @@ pub fn process_create_subscribe_user( // Check if the payer is a signer assert!(payer_account.is_signer, "Payer must be a signer"); - if !user_account.data.borrow().is_empty() { + if !user_account.data_is_empty() { return Err(ProgramError::AccountAlreadyInitialized); } if accesspass_account.data_is_empty() { @@ -85,7 +85,8 @@ pub fn process_create_subscribe_user( "Invalid AccessPass Account Owner" ); - let globalstate = globalstate_get_next(globalstate_account)?; + let mut globalstate = GlobalState::try_from(globalstate_account)?; + globalstate.account_index += 1; let (expected_old_pda_account, bump_old_seed) = get_user_old_pda(program_id, globalstate.account_index); @@ -252,9 +253,9 @@ pub fn process_create_subscribe_user( } if pda_ver == PDAVersion::V1 { - account_create_with_seed( - user_account, + try_acc_create( &user, + user_account, payer_account, system_program, program_id, @@ -265,11 +266,11 @@ pub fn process_create_subscribe_user( &[bump_old_seed], ], )?; - globalstate_write(globalstate_account, &globalstate)?; + try_acc_write(&globalstate, globalstate_account, payer_account, accounts)?; } else { - account_create_with_seed( - user_account, + try_acc_create( &user, + user_account, payer_account, system_program, program_id, @@ -283,15 +284,9 @@ pub fn process_create_subscribe_user( )?; } - account_write(mgroup_account, &mgroup, payer_account, system_program)?; - account_write(device_account, &device, payer_account, system_program)?; - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + try_acc_write(&mgroup, mgroup_account, payer_account, accounts)?; + try_acc_write(&device, device_account, payer_account, accounts)?; + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; Ok(()) } diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/delete.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/delete.rs index 0ee385a89..9796c1636 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/delete.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/delete.rs @@ -1,17 +1,17 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, pda::get_accesspass_pda, + serializer::try_acc_write, state::{ accesspass::{AccessPass, AccessPassStatus}, - accounttype::AccountTypeInfo, + globalstate::GlobalState, user::*, }, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -71,7 +71,7 @@ pub fn process_delete_user( let mut user: User = User::try_from(user_account)?; - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) && user.owner != *payer_account.key { @@ -120,19 +120,13 @@ pub fn process_delete_user( if accesspass.connection_count == 0 && accesspass.allow_multiple_ip() { accesspass.client_ip = Ipv4Addr::UNSPECIFIED; // reset to allow multiple IPs } - resize_account_if_needed( - accesspass_account, - payer_account, - accounts, - accesspass.size(), - )?; - accesspass.try_serialize(accesspass_account)?; + + try_acc_write(&accesspass, accesspass_account, payer_account, accounts)?; } user.status = UserStatus::Deleting; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Deleting: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/reject.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/reject.rs index bf609ca3e..c1507e51a 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/reject.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/reject.rs @@ -1,11 +1,11 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - state::{accounttype::AccountTypeInfo, user::*}, + serializer::try_acc_write, + state::{globalstate::GlobalState, user::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; -use doublezero_program_common::{resize_account::resize_account_if_needed, types::NetworkV4}; +use doublezero_program_common::types::NetworkV4; use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint::ProgramResult, @@ -57,7 +57,7 @@ pub fn process_reject_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -74,8 +74,7 @@ pub fn process_reject_user( user.status = UserStatus::Rejected; msg!("Reason: {:?}", value.reason); - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Rejected: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/requestban.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/requestban.rs index dc133237c..99be54122 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/requestban.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/requestban.rs @@ -1,12 +1,12 @@ use crate::{ error::DoubleZeroError, - globalstate::globalstate_get, - state::{accounttype::AccountTypeInfo, user::*}, + serializer::try_acc_write, + state::{globalstate::GlobalState, user::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -56,7 +56,7 @@ pub fn process_request_ban_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -64,8 +64,7 @@ pub fn process_request_ban_user( let mut user: User = User::try_from(user_account)?; user.status = UserStatus::PendingBan; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Deleting: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/resume.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/resume.rs index f2e7f0524..e0b57cf26 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/resume.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/resume.rs @@ -1,11 +1,12 @@ use crate::{ error::DoubleZeroError, - state::{accesspass::AccessPass, accounttype::AccountTypeInfo, user::*}, + serializer::try_acc_write, + state::{accesspass::AccessPass, user::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; use core::fmt; -use doublezero_program_common::resize_account::resize_account_if_needed; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -71,8 +72,7 @@ pub fn process_resume_user( user.try_activate(&mut accesspass)?; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Resumed: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/suspend.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/suspend.rs index 648140c4b..b8572fd25 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/suspend.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/suspend.rs @@ -1,10 +1,7 @@ -use crate::{ - error::DoubleZeroError, - state::{accounttype::AccountTypeInfo, user::*}, -}; +use crate::{error::DoubleZeroError, serializer::try_acc_write, state::user::*}; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; -use doublezero_program_common::resize_account::resize_account_if_needed; + #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -58,8 +55,7 @@ pub fn process_suspend_user( user.status = UserStatus::Suspended; - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; #[cfg(test)] msg!("Suspended: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/update.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/update.rs index ec1db6ec2..eef40f833 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/update.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/update.rs @@ -1,13 +1,13 @@ use crate::{ error::DoubleZeroError, format_option, - globalstate::globalstate_get, - helper::*, - state::{accounttype::AccountTypeInfo, user::*}, + helper::format_option_displayable, + serializer::try_acc_write, + state::{globalstate::GlobalState, user::*}, }; use borsh::BorshSerialize; use borsh_incremental::BorshDeserializeIncremental; -use doublezero_program_common::{resize_account::resize_account_if_needed, types::NetworkV4}; +use doublezero_program_common::types::NetworkV4; #[cfg(test)] use solana_program::msg; use solana_program::{ @@ -73,7 +73,7 @@ pub fn process_update_user( // Check if the account is writable assert!(user_account.is_writable, "PDA Account is not writable"); - let globalstate = globalstate_get(globalstate_account)?; + let globalstate = GlobalState::try_from(globalstate_account)?; if !globalstate.foundation_allowlist.contains(payer_account.key) { return Err(DoubleZeroError::NotAllowed.into()); } @@ -99,8 +99,8 @@ pub fn process_update_user( user.validator_pubkey = value; } - resize_account_if_needed(user_account, payer_account, accounts, user.size())?; - user.try_serialize(user_account)?; + try_acc_write(&user, user_account, payer_account, accounts)?; + #[cfg(test)] msg!("Updated: {:?}", user); diff --git a/smartcontract/programs/doublezero-serviceability/src/serializer.rs b/smartcontract/programs/doublezero-serviceability/src/serializer.rs new file mode 100644 index 000000000..a7739de09 --- /dev/null +++ b/smartcontract/programs/doublezero-serviceability/src/serializer.rs @@ -0,0 +1,102 @@ +use crate::error::Validate; +use borsh::BorshSerialize; +use doublezero_program_common::{ + create_account::try_create_account, resize_account::resize_account_if_needed, +}; +use solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, + pubkey::Pubkey, system_program, +}; +use std::fmt::Debug; + +#[cfg(test)] +use solana_program::msg; + +pub fn try_acc_create<'a, T>( + value: &T, + account: &AccountInfo<'a>, + payer_account: &AccountInfo<'a>, + system_program: &AccountInfo<'a>, + program_id: &Pubkey, + new_account_signer_seeds: &[&[u8]], +) -> ProgramResult +where + T: BorshSerialize + Validate + Debug, +{ + // Validate the instance + value.validate()?; + + let account_space = borsh::object_length(value)?; + + #[cfg(test)] + { + use solana_sdk::{rent::Rent, sysvar::Sysvar}; + + let rent = Rent::get().expect("Unable to get rent"); + let required_lamports = rent.minimum_balance(account_space); + msg!("Rent: {}", required_lamports); + } + // Create the index account + try_create_account( + payer_account.key, // Account paying for the new account + account.key, // Account to be created + account.lamports(), // Current amount of lamports on the new account + account_space, // Size in bytes to allocate for the data field + program_id, // Set program owner to our program + &[ + account.clone(), + payer_account.clone(), + system_program.clone(), + ], + new_account_signer_seeds, + )?; + + let mut account_data = &mut account.data.borrow_mut()[..]; + value.serialize(&mut account_data).unwrap(); + + #[cfg(test)] + msg!("Created: {:?}", value); + + Ok(()) +} + +// Generic serialization function for any type that implements Validate and BorshSerialize +pub fn try_acc_write( + value: &T, + account: &AccountInfo, + payer: &AccountInfo, + accounts: &[AccountInfo], +) -> ProgramResult +where + T: Validate + borsh::BorshSerialize, +{ + // Validate before serializing + value.validate()?; + + // Resize account if needed + resize_account_if_needed(account, payer, accounts, borsh::object_length(value)?)?; + + // Serialize + let mut data = &mut account.data.borrow_mut()[..]; + value.serialize(&mut data)?; + + Ok(()) +} + +pub fn try_acc_close( + close_account: &AccountInfo, + receiving_account: &AccountInfo, +) -> ProgramResult { + // Transfer the rent lamports to the receiving account + **receiving_account.lamports.borrow_mut() = receiving_account + .lamports() + .checked_add(close_account.lamports()) + .ok_or(ProgramError::InsufficientFunds)?; + **close_account.lamports.borrow_mut() = 0; + + // Close the account + close_account.realloc(0, false)?; + close_account.assign(&system_program::ID); + + Ok(()) +} diff --git a/smartcontract/programs/doublezero-serviceability/src/state/accesspass.rs b/smartcontract/programs/doublezero-serviceability/src/state/accesspass.rs index f36f8d13b..d956cfc19 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/accesspass.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/accesspass.rs @@ -1,7 +1,7 @@ use crate::{ error::{DoubleZeroError, Validate}, helper::deserialize_vec_with_capacity, - state::accounttype::{AccountType, AccountTypeInfo}, + state::accounttype::AccountType, }; use borsh::{BorshDeserialize, BorshSerialize}; @@ -160,25 +160,6 @@ impl fmt::Display for AccessPass { } } -impl AccountTypeInfo for AccessPass { - fn seed(&self) -> &[u8] { - crate::seeds::SEED_ACCESS_PASS - } - fn size(&self) -> usize { - // This operation is safe because we will never overflow usize. - borsh::object_length(self).unwrap() - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn index(&self) -> u128 { - 0 // AccessPass does not have an index like other accounts - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for AccessPass { type Error = ProgramError; @@ -221,13 +202,6 @@ impl TryFrom<&AccountInfo<'_>> for AccessPass { } impl AccessPass { - pub fn try_serialize(&self, account: &AccountInfo) -> ProgramResult { - let mut data = &mut account.data.borrow_mut()[..]; - self.serialize(&mut data)?; - - Ok(()) - } - pub fn update_status(&mut self) -> ProgramResult { let clock = Clock::get()?; let mut current_epoch = clock.epoch; @@ -318,7 +292,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.bump_seed, val2.bump_seed); assert_eq!(val.accesspass_type, val2.accesspass_type); @@ -328,7 +305,11 @@ mod tests { assert_eq!(val.connection_count, val2.connection_count); assert_eq!(val.status, val2.status); assert_eq!(val.flags, val2.flags); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] @@ -355,8 +336,8 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), len, "Invalid val.size()"); - assert_eq!(len, val2.size(), "Invalid val2.size() {val2}"); + assert_eq!(borsh::object_length(&val).unwrap(), len, "Invalid Size"); + assert_eq!(len, borsh::object_length(&val2).unwrap(), "Invalid Size"); assert_eq!(val.owner, val2.owner); assert_eq!(val.bump_seed, val2.bump_seed); assert_eq!(val.accesspass_type, val2.accesspass_type); @@ -409,8 +390,8 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), len, "Invalid val.size()"); - assert_eq!(len, val2.size(), "Invalid val2.size() {val2}"); + assert_eq!(borsh::object_length(&val).unwrap(), len, "Invalid Size"); + assert_eq!(len, borsh::object_length(&val2).unwrap(), "Invalid Size"); assert_eq!(val.owner, val2.owner); assert_eq!(val.bump_seed, val2.bump_seed); assert_eq!(val.accesspass_type, val2.accesspass_type); diff --git a/smartcontract/programs/doublezero-serviceability/src/state/contributor.rs b/smartcontract/programs/doublezero-serviceability/src/state/contributor.rs index 54db66c71..4d416fe66 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/contributor.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/contributor.rs @@ -1,7 +1,6 @@ use crate::{ error::{DoubleZeroError, Validate}, - seeds::SEED_CONTRIBUTOR, - state::accounttype::{AccountType, AccountTypeInfo}, + state::accounttype::AccountType, }; use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}; @@ -102,24 +101,6 @@ impl fmt::Display for Contributor { } } -impl AccountTypeInfo for Contributor { - fn seed(&self) -> &[u8] { - SEED_CONTRIBUTOR - } - fn size(&self) -> usize { - 1 + 32 + 16 + 1 + 1 + 4 + self.code.len() + 4 + 32 - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn index(&self) -> u128 { - self.index - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for Contributor { type Error = ProgramError; @@ -227,14 +208,21 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.code, val2.code); assert_eq!(val.index, val2.index); assert_eq!(val.bump_seed, val2.bump_seed); assert_eq!(val.status, val2.status); assert_eq!(val.account_type, val2.account_type); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/src/state/device.rs b/smartcontract/programs/doublezero-serviceability/src/state/device.rs index a619f35ca..9e801c8c1 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/device.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/device.rs @@ -1,9 +1,8 @@ use crate::{ error::{DoubleZeroError, Validate}, helper::is_global, - seeds::SEED_DEVICE, state::{ - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, interface::{CurrentInterfaceVersion, Interface}, }, }; @@ -238,48 +237,6 @@ impl fmt::Display for Device { } } -impl AccountTypeInfo for Device { - fn seed(&self) -> &[u8] { - SEED_DEVICE - } - fn size(&self) -> usize { - 1 + 32 - + 16 - + 1 - + 32 - + 32 - + 1 - + 4 - + 1 - + 4 - + self.code.len() - + 4 - + 5 * self.dz_prefixes.len() - + 32 - + 32 - + 4 - + self.mgmt_vrf.len() - + 4 - + self - .interfaces - .iter() - .map(|iface| iface.size()) - .sum::() - + 4 - + 2 - + 2 - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn index(&self) -> u128 { - self.index - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for Device { type Error = ProgramError; @@ -818,7 +775,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.code, val2.code); assert_eq!(val.index, val2.index); @@ -836,7 +796,11 @@ mod tests { assert_eq!(val.interfaces, val2.interfaces); assert_eq!(val.users_count, val2.users_count); assert_eq!(val.max_users, val2.max_users); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } fn size_of_pre_dzd_metadata_device(code_len: usize, dz_prefixes_len: usize) -> usize { @@ -872,7 +836,10 @@ mod tests { // trim data to oldsize let val2 = Device::try_from(&data[..oldsize]).unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val, val2); } } diff --git a/smartcontract/programs/doublezero-serviceability/src/state/exchange.rs b/smartcontract/programs/doublezero-serviceability/src/state/exchange.rs index 82b0834d3..e6f754f29 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/exchange.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/exchange.rs @@ -1,8 +1,5 @@ -use super::accounttype::{AccountType, AccountTypeInfo}; -use crate::{ - error::{DoubleZeroError, Validate}, - seeds::SEED_EXCHANGE, -}; +use super::accounttype::AccountType; +use crate::error::{DoubleZeroError, Validate}; use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}; use std::fmt; @@ -92,24 +89,6 @@ impl fmt::Display for Exchange { } } -impl AccountTypeInfo for Exchange { - fn seed(&self) -> &[u8] { - SEED_EXCHANGE - } - fn size(&self) -> usize { - 1 + 32 + 16 + 1 + 8 + 8 + 4 + 1 + 4 + self.code.len() + 4 + self.name.len() + 4 + 32 + 32 - } - fn index(&self) -> u128 { - self.index - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for Exchange { type Error = ProgramError; @@ -253,7 +232,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.code, val2.code); assert_eq!(val.name, val2.name); @@ -261,7 +243,11 @@ mod tests { assert_eq!(val.lng, val2.lng); assert_eq!(val.device1_pk, val2.device1_pk); assert_eq!(val.device2_pk, val2.device2_pk); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/src/state/globalconfig.rs b/smartcontract/programs/doublezero-serviceability/src/state/globalconfig.rs index d015fc4ac..2023d0187 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/globalconfig.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/globalconfig.rs @@ -153,7 +153,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.local_asn, val2.local_asn); assert_eq!(val.remote_asn, val2.remote_asn); @@ -161,7 +164,11 @@ mod tests { assert_eq!(val.user_tunnel_block, val2.user_tunnel_block); assert_eq!(val.multicastgroup_block, val2.multicastgroup_block); assert_eq!(val.next_bgp_community, val2.next_bgp_community); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/src/state/globalstate.rs b/smartcontract/programs/doublezero-serviceability/src/state/globalstate.rs index a59a2cef3..2bf6f247b 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/globalstate.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/globalstate.rs @@ -48,23 +48,6 @@ user_airdrop_lamports: {}", } } -impl GlobalState { - pub fn size(&self) -> usize { - 1 + 1 - + 16 - + 4 - + (self.foundation_allowlist.len() * 32) - + 4 - + (self.device_allowlist.len() * 32) - + 4 - + (self.user_allowlist.len() * 32) - + 32 - + 32 - + 8 - + 8 - } -} - impl TryFrom<&[u8]> for GlobalState { type Error = ProgramError; @@ -113,6 +96,12 @@ impl Validate for GlobalState { msg!("Invalid account type: {}", self.account_type); return Err(DoubleZeroError::InvalidAccountType); } + + if self.foundation_allowlist.is_empty() { + msg!("Foundation allowlist cannot be empty"); + return Err(DoubleZeroError::InvalidFoundationAllowlist); + } + Ok(()) } } @@ -170,14 +159,21 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.account_index, val2.account_index); assert_eq!(val.foundation_allowlist, val2.foundation_allowlist); assert_eq!(val.device_allowlist, val2.device_allowlist); assert_eq!(val.user_allowlist, val2.user_allowlist); assert_eq!(val.activator_authority_pk, val2.activator_authority_pk); assert_eq!(val.sentinel_authority_pk, val2.sentinel_authority_pk); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); assert_eq!( val.contributor_airdrop_lamports, val2.contributor_airdrop_lamports diff --git a/smartcontract/programs/doublezero-serviceability/src/state/link.rs b/smartcontract/programs/doublezero-serviceability/src/state/link.rs index 68a90b7c9..ab593bb94 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/link.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/link.rs @@ -1,7 +1,6 @@ use crate::{ error::{DoubleZeroError, Validate}, - seeds::SEED_LINK, - state::accounttype::{AccountType, AccountTypeInfo}, + state::accounttype::AccountType, }; use borsh::{BorshDeserialize, BorshSerialize}; use doublezero_program_common::types::NetworkV4; @@ -202,44 +201,6 @@ impl Default for Link { } } -impl AccountTypeInfo for Link { - fn seed(&self) -> &[u8] { - SEED_LINK - } - fn size(&self) -> usize { - 1 + 32 - + 16 - + 1 - + 32 - + 32 - + 1 - + 8 - + 4 - + 8 - + 8 - + 2 - + 5 - + 1 - + 4 - + self.code.len() - + 32 - + 4 - + self.side_a_iface_name.len() - + 4 - + self.side_z_iface_name.len() - + 8 - } - fn index(&self) -> u128 { - self.index - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for Link { type Error = ProgramError; @@ -409,7 +370,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.contributor_pk, val2.contributor_pk); assert_eq!(val.side_a_pk, val2.side_a_pk); @@ -420,7 +384,11 @@ mod tests { assert_eq!(val.code, val2.code); assert_eq!(val.side_a_iface_name, val2.side_a_iface_name); assert_eq!(val.side_z_iface_name, val2.side_z_iface_name); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/src/state/location.rs b/smartcontract/programs/doublezero-serviceability/src/state/location.rs index 4d98f0d4e..5e2c16cbf 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/location.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/location.rs @@ -1,6 +1,5 @@ use crate::{ error::{DoubleZeroError, Validate}, - seeds::SEED_LOCATION, state::accounttype::*, }; use borsh::{BorshDeserialize, BorshSerialize}; @@ -73,37 +72,6 @@ impl fmt::Display for Location { } } -impl AccountTypeInfo for Location { - fn seed(&self) -> &[u8] { - SEED_LOCATION - } - fn size(&self) -> usize { - 1 + 32 - + 16 - + 1 - + 8 - + 8 - + 4 - + 1 - + 4 - + self.code.len() - + 4 - + self.name.len() - + 4 - + self.country.len() - + 4 // reference_count - } - fn index(&self) -> u128 { - self.index - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for Location { type Error = ProgramError; @@ -232,12 +200,19 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.code, val2.code); assert_eq!(val.lat, val2.lat); assert_eq!(val.lng, val2.lng); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/src/state/multicastgroup.rs b/smartcontract/programs/doublezero-serviceability/src/state/multicastgroup.rs index 424874e30..aae50d129 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/multicastgroup.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/multicastgroup.rs @@ -1,7 +1,6 @@ use crate::{ error::{DoubleZeroError, Validate}, - seeds::SEED_MULTICAST_GROUP, - state::accounttype::{AccountType, AccountTypeInfo}, + state::accounttype::AccountType, }; use borsh::{BorshDeserialize, BorshSerialize}; use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}; @@ -125,24 +124,6 @@ impl Default for MulticastGroup { } } -impl AccountTypeInfo for MulticastGroup { - fn seed(&self) -> &[u8] { - SEED_MULTICAST_GROUP - } - fn size(&self) -> usize { - 1 + 32 + 16 + 1 + 32 + 4 + 8 + 1 + 4 + self.code.len() + 4 + 4 - } - fn index(&self) -> u128 { - self.index - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for MulticastGroup { type Error = ProgramError; @@ -310,7 +291,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.code, val2.code); assert_eq!(val.index, val2.index); @@ -327,6 +311,10 @@ mod tests { val.account_type as u8, val2.account_type as u8, "Invalid Account Type" ); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } } diff --git a/smartcontract/programs/doublezero-serviceability/src/state/programconfig.rs b/smartcontract/programs/doublezero-serviceability/src/state/programconfig.rs index 741609e96..ba733190b 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/programconfig.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/programconfig.rs @@ -1,15 +1,11 @@ use crate::{ - accounts::{AccountSeed, AccountSize}, error::{DoubleZeroError, Validate}, programversion::ProgramVersion, - seeds::{SEED_PREFIX, SEED_PROGRAM_CONFIG}, state::accounttype::AccountType, }; use borsh::{BorshDeserialize, BorshSerialize}; use core::fmt; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError, -}; +use solana_program::{account_info::AccountInfo, msg, program_error::ProgramError}; #[derive(BorshSerialize, Debug, PartialEq, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -30,23 +26,6 @@ impl fmt::Display for ProgramConfig { } } -impl AccountSeed for ProgramConfig { - fn seed(&self, seed: &mut Vec) { - seed.extend_from_slice(SEED_PREFIX); - seed.extend_from_slice(SEED_PROGRAM_CONFIG); - seed.extend_from_slice(&[self.bump_seed]); - } -} - -impl AccountSize for ProgramConfig { - fn size(&self) -> usize { - 1 // account_type - + 1 // bump_seed - + 12 // version (major + minor + patch) - + 12 // min_compatible_version (major + minor + patch) - } -} - impl TryFrom<&[u8]> for ProgramConfig { type Error = ProgramError; @@ -89,14 +68,6 @@ impl TryFrom<&AccountInfo<'_>> for ProgramConfig { res } } -impl ProgramConfig { - pub fn try_serialize(&self, account: &AccountInfo) -> ProgramResult { - let mut data = &mut account.data.borrow_mut()[..]; - self.serialize(&mut data)?; - - Ok(()) - } -} impl Validate for ProgramConfig { fn validate(&self) -> Result<(), DoubleZeroError> { @@ -158,11 +129,18 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.version.major, val2.version.major); assert_eq!(val.version.minor, val2.version.minor); assert_eq!(val.version.patch, val2.version.patch); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/src/state/user.rs b/smartcontract/programs/doublezero-serviceability/src/state/user.rs index 04d82182a..a6e648af9 100644 --- a/smartcontract/programs/doublezero-serviceability/src/state/user.rs +++ b/smartcontract/programs/doublezero-serviceability/src/state/user.rs @@ -1,10 +1,9 @@ use crate::{ error::{DoubleZeroError, Validate}, helper::{deserialize_vec_with_capacity, is_global}, - seeds::SEED_USER, state::{ accesspass::{AccessPass, AccessPassStatus, AccessPassType}, - accounttype::{AccountType, AccountTypeInfo}, + accounttype::AccountType, }, }; use borsh::{BorshDeserialize, BorshSerialize}; @@ -224,40 +223,6 @@ impl fmt::Display for User { } } -impl AccountTypeInfo for User { - fn seed(&self) -> &[u8] { - SEED_USER - } - fn size(&self) -> usize { - 1 + 32 - + 16 - + 1 - + 1 - + 32 - + 32 - + 1 - + 4 - + 4 - + 2 - + 5 - + 1 - + 4 - + self.publishers.len() * 32 - + 4 - + self.subscribers.len() * 32 - + 32 - } - fn index(&self) -> u128 { - self.index - } - fn bump_seed(&self) -> u8 { - self.bump_seed - } - fn owner(&self) -> Pubkey { - self.owner - } -} - impl TryFrom<&[u8]> for User { type Error = ProgramError; @@ -340,12 +305,6 @@ impl Validate for User { } impl User { - pub fn try_serialize(&self, account: &AccountInfo) -> ProgramResult { - let mut data = &mut account.data.borrow_mut()[..]; - self.serialize(&mut data)?; - - Ok(()) - } pub fn get_multicast_groups(&self) -> Vec { let mut groups: Vec = vec![]; @@ -448,7 +407,10 @@ mod tests { val.validate().unwrap(); val2.validate().unwrap(); - assert_eq!(val.size(), val2.size()); + assert_eq!( + borsh::object_length(&val).unwrap(), + borsh::object_length(&val2).unwrap() + ); assert_eq!(val.owner, val2.owner); assert_eq!(val.device_pk, val2.device_pk); assert_eq!(val.dz_ip, val2.dz_ip); @@ -457,7 +419,11 @@ mod tests { assert_eq!(val.subscribers, val2.subscribers); assert_eq!(val.publishers, val2.publishers); assert_eq!(val.validator_pubkey, val2.validator_pubkey); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } #[test] diff --git a/smartcontract/programs/doublezero-serviceability/tests/accounts_test.rs b/smartcontract/programs/doublezero-serviceability/tests/accounts_test.rs index 7af109a6d..3a713df2e 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/accounts_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/accounts_test.rs @@ -1,19 +1,16 @@ -use std::str::FromStr; - -use solana_program::{rent::Rent, system_program}; -use solana_program_test::*; -use solana_sdk::{ - account::Account as SolanaAccount, instruction::AccountMeta, pubkey::Pubkey, signature::Signer, - transaction::Transaction, -}; - use doublezero_serviceability::{ - accounts::AccountSize, instructions::DoubleZeroInstruction, pda::{get_globalstate_pda, get_program_config_pda}, programversion::ProgramVersion, state::{accounttype::AccountType, programconfig::ProgramConfig}, }; +use solana_program::{rent::Rent, system_program}; +use solana_program_test::*; +use solana_sdk::{ + account::Account as SolanaAccount, instruction::AccountMeta, pubkey::Pubkey, signature::Signer, + transaction::Transaction, +}; +use std::str::FromStr; #[tokio::test] async fn test_write_account_realloc_funds_from_payer() { @@ -28,7 +25,7 @@ async fn test_write_account_realloc_funds_from_payer() { min_compatible_version: ProgramVersion::from_str("1.0.0").unwrap(), }; - let required_space = new_program_config.size(); + let required_space = borsh::object_length(&new_program_config).unwrap(); let smaller_space = required_space / 2; let rent = Rent::default(); diff --git a/smartcontract/programs/doublezero-serviceability/tests/initialize_global_state_test.rs b/smartcontract/programs/doublezero-serviceability/tests/initialize_global_state_test.rs index 0da5d1a00..ffc4a9f9f 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/initialize_global_state_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/initialize_global_state_test.rs @@ -1,19 +1,16 @@ -use std::str::FromStr; - -use solana_program::{rent::Rent, system_program}; -use solana_program_test::*; -use solana_sdk::{ - account::Account as SolanaAccount, instruction::AccountMeta, pubkey::Pubkey, signature::Signer, - transaction::Transaction, -}; - use doublezero_serviceability::{ - accounts::AccountSize, instructions::DoubleZeroInstruction, pda::{get_globalstate_pda, get_program_config_pda}, programversion::ProgramVersion, state::{accounttype::AccountType, globalstate::GlobalState, programconfig::ProgramConfig}, }; +use solana_program::{rent::Rent, system_program}; +use solana_program_test::*; +use solana_sdk::{ + account::Account as SolanaAccount, instruction::AccountMeta, pubkey::Pubkey, signature::Signer, + transaction::Transaction, +}; +use std::str::FromStr; #[tokio::test] async fn test_initialize_global_state_resizes_programconfig_and_tops_up_rent() { @@ -28,7 +25,7 @@ async fn test_initialize_global_state_resizes_programconfig_and_tops_up_rent() { min_compatible_version: ProgramVersion::from_str("1.0.0").unwrap(), }; - let required_space = new_program_config.size(); + let required_space = borsh::object_length(&new_program_config).unwrap(); let smaller_space = required_space / 2; let rent = Rent::default(); diff --git a/smartcontract/programs/doublezero-serviceability/tests/user_migration.rs b/smartcontract/programs/doublezero-serviceability/tests/user_migration.rs index 1297173d8..c5cdbadd7 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/user_migration.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/user_migration.rs @@ -122,7 +122,7 @@ async fn test_user_migration() { .await; /***********************************************************************************************************************************/ - println!("🟢 5. Create Contributor..."); + println!("🟢 4. Create Contributor..."); let (globalstate_pubkey, _) = get_globalstate_pda(&program_id); let globalstate_account = get_globalstate(&mut banks_client, globalstate_pubkey).await; assert_eq!(globalstate_account.account_index, 2); @@ -158,7 +158,7 @@ async fn test_user_migration() { println!("✅ Contributor initialized successfully",); /***********************************************************************************************************************************/ // Device _la - println!("🟢 4. Testing Device initialization..."); + println!("🟢 5. Testing Device initialization..."); let (globalstate_pubkey, _) = get_globalstate_pda(&program_id); @@ -227,7 +227,7 @@ async fn test_user_migration() { println!("✅ Device initialized successfully",); /*****************************************************************************************************************************************************/ - println!("🟢 5. Testing Activate Device..."); + println!("🟢 6. Testing Activate Device..."); execute_transaction( &mut banks_client, recent_blockhash, @@ -251,7 +251,7 @@ async fn test_user_migration() { println!("✅ Device activated successfully"); /***********************************************************************************************************************************/ - println!("🟢 6. Testing Access Pass creation..."); + println!("🟢 7. Testing Access Pass creation..."); let user_ip = [100, 0, 0, 1].into(); let (accesspass_pubkey, _) = get_accesspass_pda(&program_id, &user_ip, &payer.pubkey()); @@ -286,7 +286,7 @@ async fn test_user_migration() { assert_eq!(user1.status, AccessPassStatus::Requested); /***********************************************************************************************************************************/ // Device _la - println!("🟢 7. Testing User creation..."); + println!("🟢 8. Testing User creation..."); let globalstate_account = get_globalstate(&mut banks_client, globalstate_pubkey).await; assert_eq!(globalstate_account.account_index, 4); @@ -324,7 +324,7 @@ async fn test_user_migration() { println!("✅ User created successfully",); /***********************************************************************************************************************************/ // Device _la - println!("🟢 8. Testing User migration..."); + println!("🟢 9. Testing User migration..."); let globalstate_account = get_globalstate(&mut banks_client, globalstate_pubkey).await; assert_eq!(globalstate_account.account_index, 5); diff --git a/smartcontract/programs/doublezero-telemetry/src/state/device_latency_samples.rs b/smartcontract/programs/doublezero-telemetry/src/state/device_latency_samples.rs index 4bd0a7cce..eb848ddd1 100644 --- a/smartcontract/programs/doublezero-telemetry/src/state/device_latency_samples.rs +++ b/smartcontract/programs/doublezero-telemetry/src/state/device_latency_samples.rs @@ -271,6 +271,10 @@ mod tests { ); assert_eq!(header.next_sample_index, header2.next_sample_index); assert_eq!(val.samples, val2.samples); - assert_eq!(data.len(), val.size(), "Invalid Size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid Size" + ); } } diff --git a/smartcontract/programs/doublezero-telemetry/src/state/internet_latency_samples.rs b/smartcontract/programs/doublezero-telemetry/src/state/internet_latency_samples.rs index 2c16b1e1d..5eb0098c7 100644 --- a/smartcontract/programs/doublezero-telemetry/src/state/internet_latency_samples.rs +++ b/smartcontract/programs/doublezero-telemetry/src/state/internet_latency_samples.rs @@ -262,6 +262,10 @@ mod tests { ); assert_eq!(header.next_sample_index, header2.next_sample_index); assert_eq!(val.samples, val2.samples); - assert_eq!(data.len(), val.size(), "Invalid size"); + assert_eq!( + data.len(), + borsh::object_length(&val).unwrap(), + "Invalid size" + ); } } diff --git a/smartcontract/sdk/rs/src/commands/globalstate/init.rs b/smartcontract/sdk/rs/src/commands/globalstate/init.rs index 5c429a258..ec95efe5d 100644 --- a/smartcontract/sdk/rs/src/commands/globalstate/init.rs +++ b/smartcontract/sdk/rs/src/commands/globalstate/init.rs @@ -12,13 +12,13 @@ pub struct InitGlobalStateCommand; impl InitGlobalStateCommand { pub fn execute(&self, client: &dyn DoubleZeroClient) -> eyre::Result { let (program_config_pubkey, _) = get_program_config_pda(&client.get_program_id()); - let (pda_pubkey, _) = get_globalstate_pda(&client.get_program_id()); + let (globalstate_pubkey, _) = get_globalstate_pda(&client.get_program_id()); client.execute_transaction( DoubleZeroInstruction::InitGlobalState(), vec![ AccountMeta::new(program_config_pubkey, false), - AccountMeta::new(pda_pubkey, false), + AccountMeta::new(globalstate_pubkey, false), ], ) }