From 3481eef08417c52f448c49427bcb160d055c4540 Mon Sep 17 00:00:00 2001 From: guibescos <59208140+guibescos@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:20:05 +0100 Subject: [PATCH] feat: allow pub to opt out (#527) --- .../src/integrity_pool/instructions.rs | 4 +- staking/integration-tests/tests/advance.rs | 2 +- .../tests/set_publisher_stake_account.rs | 40 ++++++++++++++----- .../programs/integrity-pool/src/context.rs | 3 +- staking/programs/integrity-pool/src/lib.rs | 22 +++++----- 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/staking/integration-tests/src/integrity_pool/instructions.rs b/staking/integration-tests/src/integrity_pool/instructions.rs index 383cbfa1..c2ff4463 100644 --- a/staking/integration-tests/src/integrity_pool/instructions.rs +++ b/staking/integration-tests/src/integrity_pool/instructions.rs @@ -454,7 +454,7 @@ pub fn set_publisher_stake_account( signer: &Keypair, publisher: Pubkey, current_stake_account_positions_option: Option, - new_stake_account_positions: Pubkey, + new_stake_account_positions_option: Option, ) -> TransactionResult { let pool_config = get_pool_config_address(); let pool_data: Pubkey = fetch_account_data::(svm, &pool_config).pool_data; @@ -465,7 +465,7 @@ pub fn set_publisher_stake_account( publisher, pool_data, current_stake_account_positions_option, - new_stake_account_positions, + new_stake_account_positions_option, pool_config, }; diff --git a/staking/integration-tests/tests/advance.rs b/staking/integration-tests/tests/advance.rs index 1716c5c5..6edae600 100644 --- a/staking/integration-tests/tests/advance.rs +++ b/staking/integration-tests/tests/advance.rs @@ -272,7 +272,7 @@ fn test_reward_events_with_delegation_fee() { &publisher_keypair, publisher_keypair.pubkey(), None, - publisher_stake_account_positions, + Some(publisher_stake_account_positions), ) .unwrap(); diff --git a/staking/integration-tests/tests/set_publisher_stake_account.rs b/staking/integration-tests/tests/set_publisher_stake_account.rs index 76baefe6..55c20fc3 100644 --- a/staking/integration-tests/tests/set_publisher_stake_account.rs +++ b/staking/integration-tests/tests/set_publisher_stake_account.rs @@ -69,7 +69,7 @@ fn test_set_publisher_stake_account() { &payer, publisher_keypair.pubkey(), None, - stake_account_positions, + Some(stake_account_positions), ), IntegrityPoolError::PublisherOrRewardAuthorityNeedsToSign, 0 @@ -82,7 +82,7 @@ fn test_set_publisher_stake_account() { &publisher_keypair, publisher_keypair.pubkey(), None, - stake_account_positions, + Some(stake_account_positions), ) .unwrap(); @@ -101,7 +101,7 @@ fn test_set_publisher_stake_account() { &publisher_keypair, publisher_keypair.pubkey(), Some(stake_account_positions), - stake_account_positions_2, + Some(stake_account_positions_2), ), IntegrityPoolError::StakeAccountOwnerNeedsToSign, 0 @@ -115,7 +115,7 @@ fn test_set_publisher_stake_account() { &payer, publisher_keypair.pubkey(), None, - stake_account_positions_2, + Some(stake_account_positions_2), ), ErrorCode::AccountNotEnoughKeys, 0 @@ -129,7 +129,7 @@ fn test_set_publisher_stake_account() { &payer, publisher_keypair.pubkey(), Some(stake_account_positions_2), - stake_account_positions_2, + Some(stake_account_positions_2), ), IntegrityPoolError::PublisherStakeAccountMismatch, 0 @@ -153,7 +153,7 @@ fn test_set_publisher_stake_account() { &payer, publisher_keypair.pubkey(), Some(stake_account_positions), - stake_account_positions_3, + Some(stake_account_positions_3), ), IntegrityPoolError::NewStakeAccountShouldBeUndelegated, 0 @@ -167,7 +167,7 @@ fn test_set_publisher_stake_account() { &payer, publisher_keypair.pubkey(), Some(stake_account_positions), - stake_account_positions_2, + Some(stake_account_positions_2), ) .unwrap(); @@ -196,7 +196,7 @@ fn test_set_publisher_stake_account() { &payer, publisher_keypair.pubkey(), Some(stake_account_positions_2), - stake_account_positions_3, + Some(stake_account_positions_3), ), IntegrityPoolError::CurrentStakeAccountShouldBeUndelegated, 0 @@ -210,7 +210,7 @@ fn test_set_publisher_stake_account() { &payer, Pubkey::new_unique(), Some(stake_account_positions), - stake_account_positions_2, + Some(stake_account_positions_2), ), IntegrityPoolError::PublisherNotFound, 0 @@ -402,7 +402,7 @@ fn test_set_publisher_stake_account_reward_authority() { &reward_program_authority, publisher_keypair.pubkey(), None, - stake_account_positions, + Some(stake_account_positions), ) .unwrap(); @@ -421,9 +421,27 @@ fn test_set_publisher_stake_account_reward_authority() { &reward_program_authority, publisher_keypair.pubkey(), Some(stake_account_positions), - stake_account_positions, + Some(stake_account_positions), ), IntegrityPoolError::StakeAccountOwnerNeedsToSign, 0 ); + + // publisher can opt out + set_publisher_stake_account( + &mut svm, + &payer, + &payer, + publisher_keypair.pubkey(), + Some(stake_account_positions), + None, + ) + .unwrap(); + + let pool_data: PoolData = fetch_account_data_bytemuck(&mut svm, &pool_data_pubkey); + + assert_eq!( + pool_data.publisher_stake_accounts[publisher_index], + Pubkey::default(), + ); } diff --git a/staking/programs/integrity-pool/src/context.rs b/staking/programs/integrity-pool/src/context.rs index ccc49dd5..982dfaa1 100644 --- a/staking/programs/integrity-pool/src/context.rs +++ b/staking/programs/integrity-pool/src/context.rs @@ -255,7 +255,8 @@ pub struct SetPublisherStakeAccount<'info> { pub pool_data: AccountLoader<'info, PoolData>, #[account(seeds = [POOL_CONFIG.as_bytes()], bump, has_one = pool_data)] pub pool_config: Account<'info, PoolConfig>, - pub new_stake_account_positions: AccountLoader<'info, staking::state::positions::PositionData>, + pub new_stake_account_positions_option: + Option>, pub current_stake_account_positions_option: Option>, } diff --git a/staking/programs/integrity-pool/src/lib.rs b/staking/programs/integrity-pool/src/lib.rs index b396277b..30d2a39b 100644 --- a/staking/programs/integrity-pool/src/lib.rs +++ b/staking/programs/integrity-pool/src/lib.rs @@ -228,8 +228,6 @@ pub mod integrity_pool { let publisher = &ctx.accounts.publisher; let pool_data = &mut ctx.accounts.pool_data.load_mut()?; let pool_config = &ctx.accounts.pool_config; - let new_stake_account = - DynamicPositionArray::load(&ctx.accounts.new_stake_account_positions)?; let publisher_target = TargetWithParameters::IntegrityPool { publisher: publisher.key(), @@ -269,15 +267,21 @@ pub mod integrity_pool { return Err(ErrorCode::AccountNotEnoughKeys.into()); } + if let Some(new_stake_account_positions) = &ctx.accounts.new_stake_account_positions_option + { + let new_stake_account = DynamicPositionArray::load(new_stake_account_positions)?; - // new stake account should be undelegated - require!( - !new_stake_account.has_target_with_parameters_exposure(publisher_target)?, - IntegrityPoolError::NewStakeAccountShouldBeUndelegated - ); + // new stake account should be undelegated + require!( + !new_stake_account.has_target_with_parameters_exposure(publisher_target)?, + IntegrityPoolError::NewStakeAccountShouldBeUndelegated + ); + + pool_data.publisher_stake_accounts[publisher_index] = new_stake_account_positions.key(); + } else { + pool_data.publisher_stake_accounts[publisher_index] = Pubkey::default(); + } - pool_data.publisher_stake_accounts[publisher_index] = - ctx.accounts.new_stake_account_positions.key(); Ok(()) }