Skip to content

Commit c23fc8d

Browse files
authored
[message-buffer 17/x] separate payer from admin (#819)
* feat(message-buffer): add payer to all contexts requiring lamports for rent separate admin from payer of account creation/resize/deletion * test(message-buffer): add test for same admin & payer * feat(message-buffer/scripts): keep payer & admin the same in init-buffer script for simplicity
1 parent a115d88 commit c23fc8d

File tree

11 files changed

+103
-72
lines changed

11 files changed

+103
-72
lines changed

pythnet/message_buffer/programs/message_buffer/src/instructions/create_buffer.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn create_buffer<'info>(
6666
CreateBuffer::create_account(
6767
buffer_account,
6868
target_size as usize,
69-
&ctx.accounts.admin,
69+
&ctx.accounts.payer,
7070
&[signer_seeds.as_slice()],
7171
&ctx.accounts.system_program,
7272
)?;
@@ -95,10 +95,12 @@ pub struct CreateBuffer<'info> {
9595
)]
9696
pub whitelist: Account<'info, Whitelist>,
9797

98-
// Also pays for account creation
99-
#[account(mut)]
10098
pub admin: Signer<'info>,
10199

100+
/// pays for account initialization
101+
#[account(mut)]
102+
pub payer: Signer<'info>,
103+
102104
pub system_program: Program<'info, System>,
103105
// remaining_accounts: - [AccumulatorInput PDA]
104106
}

pythnet/message_buffer/programs/message_buffer/src/instructions/delete_buffer.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ pub struct DeleteBuffer<'info> {
2525
)]
2626
pub whitelist: Account<'info, Whitelist>,
2727

28-
// Also the recipient of the lamports from closing the buffer account
29-
#[account(mut)]
3028
pub admin: Signer<'info>,
3129

30+
/// Recipient of the lamports from closing the buffer account
31+
#[account(mut)]
32+
pub payer: Signer<'info>,
33+
3234
#[account(
3335
mut,
34-
close = admin,
36+
close = payer,
3537
seeds = [allowed_program_auth.as_ref(), MESSAGE.as_bytes(), base_account_key.as_ref()],
3638
bump = message_buffer.load()?.bump,
3739
)]

pythnet/message_buffer/programs/message_buffer/src/instructions/resize_buffer.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,12 @@ pub struct ResizeBuffer<'info> {
4949
)]
5050
pub whitelist: Account<'info, Whitelist>,
5151

52-
// Also pays for account creation
53-
#[account(mut)]
5452
pub admin: Signer<'info>,
5553

54+
/// Pays for any additional rent needed to increase the buffer size
55+
#[account(mut)]
56+
pub payer: Signer<'info>,
57+
5658
pub system_program: Program<'info, System>,
5759

5860
/// If decreasing, Anchor will automatically check
@@ -64,7 +66,7 @@ pub struct ResizeBuffer<'info> {
6466
mut,
6567
realloc = target_size as usize,
6668
realloc::zero = false,
67-
realloc::payer = admin,
69+
realloc::payer = payer,
6870
seeds = [allowed_program_auth.as_ref(), MESSAGE.as_bytes(), base_account_key.as_ref()],
6971
bump = message_buffer.load()?.bump,
7072
)]

pythnet/message_buffer/programs/message_buffer/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,13 @@ pub mod message_buffer {
145145
#[derive(Accounts)]
146146
pub struct Initialize<'info> {
147147
/// Admin that can update the whitelist and create/resize/delete buffers
148+
pub admin: Signer<'info>,
149+
148150
#[account(mut)]
149-
pub admin: Signer<'info>,
151+
pub payer: Signer<'info>,
150152
#[account(
151153
init,
152-
payer = admin,
154+
payer = payer,
153155
seeds = [MESSAGE.as_bytes(), WHITELIST.as_bytes()],
154156
bump,
155157
space = 8 + Whitelist::INIT_SPACE,

pythnet/message_buffer/programs/mock-cpi-caller/tests/cases/test_create_buffer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ async fn create_buffer_with_invalid_admin_should_fail() {
5050
space,
5151
context.whitelist(),
5252
invalid_admin.pubkey(),
53+
context.payer.pubkey(),
5354
msg_buffer_pda,
5455
);
5556

@@ -80,7 +81,7 @@ async fn create_buffer_with_invalid_size_should_fail() {
8081
);
8182
let cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();
8283
let _whitelist = context.whitelist();
83-
let admin = context.default_admin();
84+
let admin = context.admin();
8485

8586
let (msg_buffer_pda, _) = find_msg_buffer_pda(cpi_caller_auth, pyth_price_acct);
8687
let invalid_create_buffer_ix = create_msg_buffer_ix(
@@ -89,6 +90,7 @@ async fn create_buffer_with_invalid_size_should_fail() {
8990
1,
9091
context.whitelist(),
9192
admin.pubkey(),
93+
context.payer.pubkey(),
9294
msg_buffer_pda,
9395
);
9496

pythnet/message_buffer/programs/mock-cpi-caller/tests/cases/test_initialize.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@ use super::*;
33
#[tokio::test]
44
async fn test_initialize() {
55
let context = &mut MessageBufferTestContext::initialize_context(false).await;
6-
let admin = context.payer.insecure_clone();
6+
let admin = Keypair::new();
7+
let (_, whitelist_bump) = context.initialize(&admin).await.unwrap();
8+
9+
let (whitelist_acct_bump, admin_pubkey, allowed_programs_len, allowed_programs) =
10+
context.fetch_whitelist().await.unwrap();
11+
12+
assert_eq!(whitelist_bump, whitelist_acct_bump);
13+
assert_eq!(admin.pubkey(), admin_pubkey);
14+
15+
assert_eq!(0, allowed_programs_len);
16+
assert_eq!(allowed_programs, vec![]);
17+
}
18+
19+
#[tokio::test]
20+
async fn test_initialize_with_payer_as_admin() {
21+
let context = &mut MessageBufferTestContext::initialize_context(false).await;
22+
let admin = &context.payer.insecure_clone();
723
let (_, whitelist_bump) = context.initialize(admin).await.unwrap();
824

925
let (whitelist_acct_bump, admin_pubkey, allowed_programs_len, allowed_programs) =
1026
context.fetch_whitelist().await.unwrap();
1127

1228
assert_eq!(whitelist_bump, whitelist_acct_bump);
13-
assert_eq!(context.payer.pubkey(), admin_pubkey);
29+
assert_eq!(admin.pubkey(), admin_pubkey);
1430

1531
assert_eq!(0, allowed_programs_len);
1632
assert_eq!(allowed_programs, vec![]);

pythnet/message_buffer/programs/mock-cpi-caller/tests/cases/test_resize_buffer.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ async fn fail_resize_buffer_invalid_increase() {
100100
.unwrap();
101101

102102
let whitelist = context.whitelist();
103-
let admin = context.default_admin();
103+
let admin = context.admin();
104104
let cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();
105105
let pyth_price_acct = MessageBufferTestContext::default_pyth_price_account();
106106
let (msg_buffer_pda, msg_buffer_bump) = MessageBufferTestContext::default_msg_buffer();
@@ -115,6 +115,7 @@ async fn fail_resize_buffer_invalid_increase() {
115115
target_size,
116116
whitelist,
117117
admin.pubkey(),
118+
context.payer.pubkey(),
118119
msg_buffer_pda,
119120
);
120121

@@ -154,6 +155,7 @@ async fn fail_resize_buffer_invalid_increase() {
154155
target_size,
155156
whitelist,
156157
admin.pubkey(),
158+
context.payer.pubkey(),
157159
msg_buffer_pda,
158160
);
159161

@@ -259,7 +261,7 @@ async fn fail_resize_initialized_buffer() {
259261
.unwrap();
260262

261263
let payer = context.payer.pubkey();
262-
let admin = context.default_admin();
264+
let admin = context.admin();
263265
let pyth_price_acct = MessageBufferTestContext::default_pyth_price_account();
264266
let whitelist = context.whitelist();
265267
let cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();
@@ -295,6 +297,7 @@ async fn fail_resize_initialized_buffer() {
295297
target_size,
296298
whitelist,
297299
admin.pubkey(),
300+
context.payer.pubkey(),
298301
msg_buffer_pda,
299302
);
300303

@@ -317,6 +320,7 @@ async fn fail_resize_initialized_buffer() {
317320
target_size,
318321
whitelist,
319322
admin.pubkey(),
323+
context.payer.pubkey(),
320324
msg_buffer_pda,
321325
);
322326

@@ -341,7 +345,7 @@ async fn fail_resize_buffer_exceed_max_size() {
341345
.unwrap();
342346

343347
let whitelist = context.whitelist();
344-
let admin = context.default_admin();
348+
let admin = context.admin();
345349
let cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();
346350
let pyth_price_acct = MessageBufferTestContext::default_pyth_price_account();
347351
let (msg_buffer_pda, _msg_buffer_bump) = MessageBufferTestContext::default_msg_buffer();
@@ -356,6 +360,7 @@ async fn fail_resize_buffer_exceed_max_size() {
356360
target_size,
357361
whitelist,
358362
admin.pubkey(),
363+
context.payer.pubkey(),
359364
msg_buffer_pda,
360365
);
361366

@@ -370,6 +375,7 @@ async fn fail_resize_buffer_exceed_max_size() {
370375
target_size,
371376
whitelist,
372377
admin.pubkey(),
378+
context.payer.pubkey(),
373379
msg_buffer_pda,
374380
);
375381

pythnet/message_buffer/programs/mock-cpi-caller/tests/cases/test_set_allowed_programs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use super::*;
33
#[tokio::test]
44
async fn test_set_allowed_programs() {
55
let context = &mut MessageBufferTestContext::initialize_context(false).await;
6-
let admin = context.default_admin();
7-
context.initialize(admin).await.unwrap();
6+
let admin = Keypair::new();
7+
context.initialize(&admin).await.unwrap();
88

99

1010
let mock_cpi_caller_auth = MessageBufferTestContext::get_mock_cpi_auth();

pythnet/message_buffer/programs/mock-cpi-caller/tests/program_test/mod.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ impl MessageBufferTestContext {
9898
disable_loosen_cpi_limit: bool,
9999
) -> Result<Self> {
100100
let mut context = Self::initialize_context(disable_loosen_cpi_limit).await;
101-
context.initialize(context.default_admin()).await.unwrap();
101+
let admin = Keypair::new();
102+
context.initialize(&admin).await.unwrap();
102103
context
103104
.set_allowed_programs(&Self::default_allowed_programs())
104105
.await
@@ -127,8 +128,8 @@ impl MessageBufferTestContext {
127128
self.context.banks_client.get_balance(pubkey).await.unwrap()
128129
}
129130

130-
pub fn default_admin(&self) -> Keypair {
131-
self.payer.insecure_clone()
131+
pub fn admin(&self) -> Keypair {
132+
self.admin.as_ref().unwrap().insecure_clone()
132133
}
133134

134135
fn admin_pubkey(&self) -> Pubkey {
@@ -204,7 +205,7 @@ impl MessageBufferTestContext {
204205
}
205206
}
206207

207-
pub async fn initialize(&mut self, admin: Keypair) -> Result<(Pubkey, u8)> {
208+
pub async fn initialize(&mut self, admin: &Keypair) -> Result<(Pubkey, u8)> {
208209
let (whitelist_pda, whitelist_bump) = Pubkey::find_program_address(
209210
&[MESSAGE.as_bytes(), WHITELIST.as_bytes()],
210211
&::message_buffer::id(),
@@ -213,7 +214,8 @@ impl MessageBufferTestContext {
213214
self.admin = Some(admin.insecure_clone());
214215
self.whitelist = Some(whitelist_pda);
215216

216-
let init_message_buffer_ix = initialize_ix(admin.pubkey(), whitelist_pda);
217+
let init_message_buffer_ix =
218+
initialize_ix(admin.pubkey(), self.payer.pubkey(), whitelist_pda);
217219

218220
self.process_ixs(
219221
&[init_message_buffer_ix],
@@ -266,6 +268,7 @@ impl MessageBufferTestContext {
266268
target_size,
267269
self.whitelist(),
268270
admin.pubkey(),
271+
self.payer.pubkey(),
269272
msg_buffer_pda,
270273
);
271274
self.process_ixs(&[create_msg_buffer_ix], vec![&admin])
@@ -291,13 +294,14 @@ impl MessageBufferTestContext {
291294

292295
let (msg_buffer_pda, _) =
293296
find_msg_buffer_pda(Self::get_mock_cpi_auth(), pyth_price_account);
294-
let admin = self.admin.as_ref().unwrap().insecure_clone();
297+
let admin = self.admin();
295298

296299
let delete_ix = delete_msg_buffer_ix(
297300
Self::get_mock_cpi_auth(),
298301
pyth_price_account,
299302
self.whitelist(),
300303
admin.pubkey(),
304+
self.payer.pubkey(),
301305
msg_buffer_pda,
302306
);
303307

@@ -326,6 +330,7 @@ impl MessageBufferTestContext {
326330
target_size,
327331
self.whitelist(),
328332
admin.pubkey(),
333+
self.payer.pubkey(),
329334
msg_buffer_pda,
330335
);
331336
resize_ixs.push(resize_ix);
@@ -366,14 +371,15 @@ impl MessageBufferTestContext {
366371

367372
pub type AddPriceParams = (u64, u64, u64, u64, u64);
368373

369-
fn initialize_ix(admin: Pubkey, whitelist_pda: Pubkey) -> Instruction {
374+
fn initialize_ix(admin: Pubkey, payer: Pubkey, whitelist_pda: Pubkey) -> Instruction {
370375
let init_ix_discriminator = sighash("global", "initialize");
371376

372377
Instruction::new_with_borsh(
373378
::message_buffer::id(),
374379
&(init_ix_discriminator),
375380
vec![
376-
AccountMeta::new(admin, true),
381+
AccountMeta::new_readonly(admin, true),
382+
AccountMeta::new(payer, true),
377383
AccountMeta::new(whitelist_pda, false),
378384
AccountMeta::new_readonly(System::id(), false),
379385
],
@@ -403,6 +409,7 @@ pub fn create_msg_buffer_ix(
403409
target_size: u32,
404410
whitelist: Pubkey,
405411
admin: Pubkey,
412+
payer: Pubkey,
406413
msg_buffer_pda: Pubkey,
407414
) -> Instruction {
408415
let create_ix_discriminator = sighash("global", "create_buffer");
@@ -417,7 +424,8 @@ pub fn create_msg_buffer_ix(
417424
),
418425
vec![
419426
AccountMeta::new_readonly(whitelist, false),
420-
AccountMeta::new(admin, true),
427+
AccountMeta::new_readonly(admin, true),
428+
AccountMeta::new(payer, true),
421429
AccountMeta::new_readonly(System::id(), false),
422430
AccountMeta::new(msg_buffer_pda, false),
423431
],
@@ -431,6 +439,7 @@ pub fn resize_msg_buffer_ix(
431439
target_size: u32,
432440
whitelist: Pubkey,
433441
admin: Pubkey,
442+
payer: Pubkey,
434443
msg_buffer_pda: Pubkey,
435444
) -> Instruction {
436445
let resize_ix_disc = sighash("global", "resize_buffer");
@@ -445,7 +454,8 @@ pub fn resize_msg_buffer_ix(
445454
),
446455
vec![
447456
AccountMeta::new_readonly(whitelist, false),
448-
AccountMeta::new(admin, true),
457+
AccountMeta::new_readonly(admin, true),
458+
AccountMeta::new(payer, true),
449459
AccountMeta::new_readonly(System::id(), false),
450460
AccountMeta::new(msg_buffer_pda, false),
451461
],
@@ -458,6 +468,7 @@ pub fn delete_msg_buffer_ix(
458468
pyth_price_acct: Pubkey,
459469
whitelist: Pubkey,
460470
admin: Pubkey,
471+
payer: Pubkey,
461472
msg_buffer_pda: Pubkey,
462473
) -> Instruction {
463474
let delete_ix_disc = sighash("global", "delete_buffer");
@@ -467,7 +478,8 @@ pub fn delete_msg_buffer_ix(
467478
&(delete_ix_disc, cpi_caller_auth, pyth_price_acct),
468479
vec![
469480
AccountMeta::new_readonly(whitelist, false),
470-
AccountMeta::new(admin, true),
481+
AccountMeta::new_readonly(admin, true),
482+
AccountMeta::new(payer, true),
471483
AccountMeta::new(msg_buffer_pda, false),
472484
],
473485
)

pythnet/message_buffer/scripts/setup_message_buffer.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,8 @@ async function main() {
8686
...(await provider.connection.getLatestBlockhash()),
8787
});
8888

89-
const whitelistAdminBalance = await provider.connection.getBalance(
90-
whitelistAdmin.publicKey
91-
);
92-
console.log(`whitelistAdminBalance: ${whitelistAdminBalance}`);
89+
const payerBalance = await provider.connection.getBalance(payer.publicKey);
90+
console.log(`payerBalance: ${payerBalance}`);
9391
console.log("Airdrop complete");
9492
console.groupEnd();
9593

@@ -103,7 +101,9 @@ async function main() {
103101
.initialize()
104102
.accounts({
105103
admin: whitelistAdmin.publicKey,
104+
payer: payer.publicKey,
106105
})
106+
.signers([whitelistAdmin, payer])
107107
.rpc();
108108

109109
console.log(`initializeTxnSig: ${initializeTxnSig}`);

0 commit comments

Comments
 (0)