From 05f2682013b75f2ffdf76ec39dac65654416adb6 Mon Sep 17 00:00:00 2001 From: Jean Marchand Date: Thu, 25 Apr 2024 09:40:14 +0200 Subject: [PATCH] Split instructions --- cli/src/processor/worker.rs | 52 +++++++----- .../network/src/instructions/initialize.rs | 2 +- programs/network/src/instructions/mod.rs | 2 + .../network/src/instructions/worker_create.rs | 81 +++---------------- .../src/instructions/worker_utils_create.rs | 64 +++++++++++++++ .../src/jobs/distribute_fees/process_entry.rs | 7 +- .../src/jobs/distribute_fees/process_frame.rs | 7 +- programs/network/src/lib.rs | 8 +- programs/network/src/state/fee.rs | 15 ++-- programs/network/src/state/penalty.rs | 6 +- programs/network/src/state/registry.rs | 6 +- programs/network/src/state/worker.rs | 13 ++- .../thread/src/instructions/thread_exec.rs | 2 +- 13 files changed, 148 insertions(+), 117 deletions(-) create mode 100644 programs/network/src/instructions/worker_utils_create.rs diff --git a/cli/src/processor/worker.rs b/cli/src/processor/worker.rs index 0bb425c9..969674ba 100644 --- a/cli/src/processor/worker.rs +++ b/cli/src/processor/worker.rs @@ -6,10 +6,7 @@ use anchor_spl::{associated_token, associated_token::get_associated_token_addres use sablier_network_program::state::{ Config, Fee, Penalty, Registry, Snapshot, SnapshotFrame, Worker, WorkerSettings, }; -use solana_sdk::{ - instruction::AccountMeta, - signature::{Keypair, Signer}, -}; +use solana_sdk::signature::{Keypair, Signer}; use crate::{client::Client, errors::CliError}; @@ -91,29 +88,42 @@ pub fn create(client: &Client, signatory: Keypair, silent: bool) -> Result<(), C // Build ix let worker_id = registry.total_workers; let worker_pubkey = Worker::pubkey(worker_id); - let mut accounts = sablier_network_program::accounts::WorkerCreate { - associated_token_program: associated_token::ID, - authority: client.payer_pubkey(), - config: Config::pubkey(), - fee: Fee::pubkey(worker_pubkey), - mint: config.mint, - registry: Registry::pubkey(), - system_program: system_program::ID, - token_program: token::ID, - worker: worker_pubkey, - worker_tokens: get_associated_token_address(&worker_pubkey, &config.mint), - } - .to_account_metas(Some(false)); - accounts.push(AccountMeta::new_readonly(signatory.pubkey(), true)); - accounts.push(AccountMeta::new(Penalty::pubkey(worker_pubkey), false)); let ix = Instruction { program_id: sablier_network_program::ID, - accounts, + accounts: sablier_network_program::accounts::WorkerCreate { + associated_token_program: associated_token::ID, + authority: client.payer_pubkey(), + config: Config::pubkey(), + // fee: Fee::pubkey(worker_pubkey), + signatory: signatory.pubkey(), + mint: config.mint, + registry: Registry::pubkey(), + system_program: system_program::ID, + token_program: token::ID, + worker: worker_pubkey, + worker_tokens: get_associated_token_address(&worker_pubkey, &config.mint), + } + .to_account_metas(Some(false)), data: sablier_network_program::instruction::WorkerCreate {}.data(), }; + + let worker_pubkey = Worker::pubkey(worker_id + 1); + let ix_utils = Instruction { + program_id: sablier_network_program::ID, + accounts: sablier_network_program::accounts::WorkerUtilsCreate { + authority: client.payer_pubkey(), + worker: worker_pubkey, + registry: Registry::pubkey(), + fee: Fee::pubkey(worker_pubkey), + penalty: Penalty::pubkey(worker_pubkey), + system_program: system_program::ID, + } + .to_account_metas(Some(false)), + data: sablier_network_program::instruction::WorkerUtilsCreate {}.data(), + }; client - .send_and_confirm(&[ix], &[client.payer(), &signatory]) + .send_and_confirm(&[ix, ix_utils], &[client.payer(), &signatory]) .unwrap(); if !silent { get(client, worker_id)?; diff --git a/programs/network/src/instructions/initialize.rs b/programs/network/src/instructions/initialize.rs index 078e9a0a..0460d9ed 100644 --- a/programs/network/src/instructions/initialize.rs +++ b/programs/network/src/instructions/initialize.rs @@ -54,7 +54,7 @@ pub fn handler(ctx: Context) -> Result<()> { // Initialize accounts. config.init(admin.key(), mint.key())?; - registry.init()?; + registry.init(ctx.bumps.registry)?; snapshot.init(0)?; Ok(()) diff --git a/programs/network/src/instructions/mod.rs b/programs/network/src/instructions/mod.rs index a8abc67a..14e75bc5 100644 --- a/programs/network/src/instructions/mod.rs +++ b/programs/network/src/instructions/mod.rs @@ -14,6 +14,7 @@ pub mod unstake_create; pub mod worker_claim; pub mod worker_create; pub mod worker_update; +pub mod worker_utils_create; pub use config_update::*; pub use delegation_claim::*; @@ -31,3 +32,4 @@ pub use unstake_create::*; pub use worker_claim::*; pub use worker_create::*; pub use worker_update::*; +pub use worker_utils_create::*; diff --git a/programs/network/src/instructions/worker_create.rs b/programs/network/src/instructions/worker_create.rs index 741ea4ce..c7e4c4c0 100644 --- a/programs/network/src/instructions/worker_create.rs +++ b/programs/network/src/instructions/worker_create.rs @@ -15,18 +15,6 @@ pub struct WorkerCreate<'info> { #[account(address = Config::pubkey())] pub config: AccountLoader<'info, Config>, - #[account( - init, - seeds = [ - SEED_FEE, - worker.key().as_ref(), - ], - bump, - payer = authority, - space = 8 + Fee::INIT_SPACE, - )] - pub fee: AccountLoader<'info, Fee>, - #[account(address = config.load()?.mint)] pub mint: Box>, @@ -38,6 +26,9 @@ pub struct WorkerCreate<'info> { )] pub registry: Box>, + #[account(constraint = signatory.key() != authority.key() @ SablierError::InvalidSignatory)] + pub signatory: Signer<'info>, + #[account( init, seeds = [ @@ -65,70 +56,20 @@ pub struct WorkerCreate<'info> { pub token_program: Program<'info, Token>, } -pub fn handler<'info>(ctx: Context<'_, '_, 'info, 'info, WorkerCreate<'info>>) -> Result<()> { +pub fn handler(ctx: Context) -> Result<()> { // Get accounts let authority = &mut ctx.accounts.authority; - let fee = &mut ctx.accounts.fee; let registry = &mut ctx.accounts.registry; let worker = &mut ctx.accounts.worker; - - let signatory = { - let signatory_info = ctx - .remaining_accounts - .first() - .ok_or(ErrorCode::AccountNotEnoughKeys)?; - - if !signatory_info.is_signer { - return Err(ErrorCode::AccountNotSigner.into()); - } - - if signatory_info.key == authority.key { - return Err(SablierError::InvalidSignatory.into()); - } - - Signer::try_from(signatory_info)? - }; - - let mut penalty: Account = { - let penalty_info = ctx - .remaining_accounts - .get(1) - .ok_or(ErrorCode::AccountNotEnoughKeys)?; - - if !penalty_info.is_writable { - return Err(ErrorCode::AccountNotMutable.into()); - } - - let (pda_key, bump) = - Pubkey::find_program_address(&[SEED_PENALTY, worker.key().as_ref()], &crate::ID); - - if &pda_key != penalty_info.key { - return Err(ErrorCode::ConstraintSeeds.into()); - } - - let account_space = 8 + Penalty::INIT_SPACE; - let lamports = Rent::get()?.minimum_balance(account_space); - let cpi_accounts = anchor_lang::system_program::CreateAccount { - from: authority.to_account_info(), - to: penalty_info.to_owned(), - }; - let cpi_context = anchor_lang::context::CpiContext::new( - ctx.accounts.system_program.to_account_info(), - cpi_accounts, - ); - anchor_lang::system_program::create_account( - cpi_context.with_signer(&[&[SEED_PENALTY, worker.key().as_ref(), &[bump][..]][..]]), - lamports, - account_space as u64, - &crate::ID, - )?; - Account::try_from_unchecked(penalty_info)? - }; + let signatory = &mut ctx.accounts.signatory; // Initialize the worker accounts. - worker.init(authority, registry.total_workers, &signatory)?; - fee.init(worker.key())?; - penalty.init(worker.key())?; + worker.init( + authority, + registry.total_workers, + signatory, + ctx.bumps.worker, + )?; // Update the registry's worker counter. registry.total_workers += 1; diff --git a/programs/network/src/instructions/worker_utils_create.rs b/programs/network/src/instructions/worker_utils_create.rs new file mode 100644 index 00000000..ab9c837f --- /dev/null +++ b/programs/network/src/instructions/worker_utils_create.rs @@ -0,0 +1,64 @@ +use anchor_lang::prelude::*; + +use crate::{ + constants::{SEED_FEE, SEED_PENALTY, SEED_REGISTRY, SEED_WORKER}, + Fee, FeeAccount, Penalty, PenaltyAccount, Registry, Worker, +}; + +#[derive(Accounts)] +pub struct WorkerUtilsCreate<'info> { + #[account(mut)] + pub authority: Signer<'info>, + + #[account( + seeds = [ + SEED_WORKER, + registry.total_workers.to_be_bytes().as_ref(), + ], + bump = worker.bump, + )] + pub worker: Account<'info, Worker>, + + #[account( + seeds = [SEED_REGISTRY], + bump = registry.bump, + )] + pub registry: Account<'info, Registry>, + + #[account( + init, + seeds = [ + SEED_FEE, + worker.key().as_ref(), + ], + bump, + payer = authority, + space = 8 + Fee::INIT_SPACE, + )] + pub fee: Account<'info, Fee>, + + #[account( + init, + seeds = [ + SEED_PENALTY, + worker.key().as_ref(), + ], + bump, + payer = authority, + space = 8 + Penalty::INIT_SPACE, + )] + pub penalty: Account<'info, Penalty>, + + pub system_program: Program<'info, System>, +} + +pub fn handler(ctx: Context) -> Result<()> { + let worker = &mut ctx.accounts.worker; + let fee = &mut ctx.accounts.fee; + let penalty = &mut ctx.accounts.penalty; + + fee.init(worker.key(), ctx.bumps.fee)?; + penalty.init(worker.key(), ctx.bumps.penalty)?; + + Ok(()) +} diff --git a/programs/network/src/jobs/distribute_fees/process_entry.rs b/programs/network/src/jobs/distribute_fees/process_entry.rs index 80e31b83..2618b38a 100644 --- a/programs/network/src/jobs/distribute_fees/process_entry.rs +++ b/programs/network/src/jobs/distribute_fees/process_entry.rs @@ -25,12 +25,12 @@ pub struct DistributeFeesProcessEntry<'info> { mut, seeds = [ SEED_FEE, - fee.load()?.worker.as_ref(), + fee.worker.as_ref(), ], bump, has_one = worker, )] - pub fee: AccountLoader<'info, Fee>, + pub fee: Account<'info, Fee>, #[account(address = Registry::pubkey())] pub registry: Account<'info, Registry>, @@ -66,7 +66,6 @@ pub fn handler(ctx: Context) -> Result) -> Result 0 { - fee_data.distributable_balance * snapshot_entry.stake_amount / snapshot_frame.stake_amount + fee.distributable_balance * snapshot_entry.stake_amount / snapshot_frame.stake_amount } else { 0 }; diff --git a/programs/network/src/jobs/distribute_fees/process_frame.rs b/programs/network/src/jobs/distribute_fees/process_frame.rs index c835f890..127ffefe 100644 --- a/programs/network/src/jobs/distribute_fees/process_frame.rs +++ b/programs/network/src/jobs/distribute_fees/process_frame.rs @@ -12,12 +12,12 @@ pub struct DistributeFeesProcessFrame<'info> { mut, seeds = [ SEED_FEE, - fee.load()?.worker.as_ref(), + fee.worker.as_ref(), ], bump, has_one = worker, )] - pub fee: AccountLoader<'info, Fee>, + pub fee: Account<'info, Fee>, #[account(address = Registry::pubkey())] pub registry: Account<'info, Registry>, @@ -46,7 +46,6 @@ pub fn handler(ctx: Context) -> Result) -> Result 0 { diff --git a/programs/network/src/lib.rs b/programs/network/src/lib.rs index 8d67b021..3d99234c 100644 --- a/programs/network/src/lib.rs +++ b/programs/network/src/lib.rs @@ -78,12 +78,14 @@ pub mod network_program { worker_claim::handler(ctx, amount) } - pub fn worker_create<'info>( - ctx: Context<'_, '_, 'info, 'info, WorkerCreate<'info>>, - ) -> Result<()> { + pub fn worker_create(ctx: Context) -> Result<()> { worker_create::handler(ctx) } + pub fn worker_utils_create(ctx: Context) -> Result<()> { + worker_utils_create::handler(ctx) + } + pub fn worker_update(ctx: Context, settings: WorkerSettings) -> Result<()> { worker_update::handler(ctx, settings) } diff --git a/programs/network/src/state/fee.rs b/programs/network/src/state/fee.rs index bd014962..5836c81e 100644 --- a/programs/network/src/state/fee.rs +++ b/programs/network/src/state/fee.rs @@ -3,13 +3,14 @@ use anchor_lang::prelude::*; use crate::constants::SEED_FEE; /// Escrows the lamport balance owed to a particular worker. -#[account(zero_copy)] +#[account] #[derive(Debug, InitSpace)] pub struct Fee { /// The number of lamports that are distributable for this epoch period. pub distributable_balance: u64, /// The worker who received the fees. pub worker: Pubkey, + pub bump: u8, } impl Fee { @@ -27,14 +28,14 @@ impl Fee { /// Trait for reading and writing to a fee account. pub trait FeeAccount { /// Initialize the account to hold fee object. - fn init(&mut self, worker: Pubkey) -> Result<()>; + fn init(&mut self, worker: Pubkey, bump: u8) -> Result<()>; } -impl FeeAccount for AccountLoader<'_, Fee> { - fn init(&mut self, worker: Pubkey) -> Result<()> { - let mut fee = self.load_init()?; - fee.distributable_balance = 0; - fee.worker = worker; +impl FeeAccount for Account<'_, Fee> { + fn init(&mut self, worker: Pubkey, bump: u8) -> Result<()> { + self.distributable_balance = 0; + self.worker = worker; + self.bump = bump; Ok(()) } } diff --git a/programs/network/src/state/penalty.rs b/programs/network/src/state/penalty.rs index aaef21ab..5c4a9b8b 100644 --- a/programs/network/src/state/penalty.rs +++ b/programs/network/src/state/penalty.rs @@ -8,6 +8,7 @@ use crate::constants::SEED_PENALTY; pub struct Penalty { /// The worker who was penalized. pub worker: Pubkey, + pub bump: u8, } impl Penalty { @@ -23,7 +24,7 @@ pub trait PenaltyAccount { fn pubkey(&self) -> Pubkey; /// Initialize the account to hold penalty object. - fn init(&mut self, worker: Pubkey) -> Result<()>; + fn init(&mut self, worker: Pubkey, bump: u8) -> Result<()>; } impl PenaltyAccount for Account<'_, Penalty> { @@ -31,8 +32,9 @@ impl PenaltyAccount for Account<'_, Penalty> { Penalty::pubkey(self.worker) } - fn init(&mut self, worker: Pubkey) -> Result<()> { + fn init(&mut self, worker: Pubkey, bump: u8) -> Result<()> { self.worker = worker; + self.bump = bump; Ok(()) } } diff --git a/programs/network/src/state/registry.rs b/programs/network/src/state/registry.rs index 74a52c72..1f9da692 100644 --- a/programs/network/src/state/registry.rs +++ b/programs/network/src/state/registry.rs @@ -18,6 +18,7 @@ pub struct Registry { pub total_pools: u64, pub total_unstakes: u64, pub total_workers: u64, + pub bump: u8, } impl Registry { @@ -31,16 +32,17 @@ impl Registry { */ pub trait RegistryAccount { - fn init(&mut self) -> Result<()>; + fn init(&mut self, bump: u8) -> Result<()>; fn hash_nonce(&mut self) -> Result<()>; } impl RegistryAccount for Account<'_, Registry> { - fn init(&mut self) -> Result<()> { + fn init(&mut self, bump: u8) -> Result<()> { self.current_epoch = 0; self.locked = false; self.total_workers = 0; + self.bump = bump; Ok(()) } diff --git a/programs/network/src/state/worker.rs b/programs/network/src/state/worker.rs index 25aa4818..f4388e11 100644 --- a/programs/network/src/state/worker.rs +++ b/programs/network/src/state/worker.rs @@ -18,6 +18,7 @@ pub struct Worker { pub signatory: Pubkey, /// The number delegations allocated to this worker. pub total_delegations: u64, + pub bump: u8, } impl Worker { @@ -37,7 +38,8 @@ pub struct WorkerSettings { pub trait WorkerAccount { fn pubkey(&self) -> Pubkey; - fn init(&mut self, authority: &mut Signer, id: u64, signatory: &Signer) -> Result<()>; + fn init(&mut self, authority: &mut Signer, id: u64, signatory: &Signer, bump: u8) + -> Result<()>; fn update(&mut self, settings: WorkerSettings) -> Result<()>; } @@ -47,13 +49,20 @@ impl WorkerAccount for Account<'_, Worker> { Worker::pubkey(self.id) } - fn init(&mut self, authority: &mut Signer, id: u64, signatory: &Signer) -> Result<()> { + fn init( + &mut self, + authority: &mut Signer, + id: u64, + signatory: &Signer, + bump: u8, + ) -> Result<()> { self.authority = authority.key(); self.commission_balance = 0; self.commission_rate = 0; self.id = id; self.signatory = signatory.key(); self.total_delegations = 0; + self.bump = bump; Ok(()) } diff --git a/programs/thread/src/instructions/thread_exec.rs b/programs/thread/src/instructions/thread_exec.rs index 618d84f5..82192dc8 100644 --- a/programs/thread/src/instructions/thread_exec.rs +++ b/programs/thread/src/instructions/thread_exec.rs @@ -25,7 +25,7 @@ pub struct ThreadExec<'info> { seeds::program = sablier_network_program::ID, has_one = worker, )] - pub fee: AccountLoader<'info, Fee>, + pub fee: Account<'info, Fee>, /// The active worker pool. #[account(address = Pool::pubkey(POOL_ID))]