Skip to content

Commit 9fea461

Browse files
authored
feat(accumulator-updater): add funding account for AccumulatorInput creation (#771)
1 parent 0ac7712 commit 9fea461

File tree

6 files changed

+53
-12
lines changed

6 files changed

+53
-12
lines changed

accumulator_updater/programs/accumulator_updater/src/instructions/put_all.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use {
1414

1515

1616
pub const ACCUMULATOR: &[u8; 11] = b"accumulator";
17+
pub const FUND: &[u8; 4] = b"fund";
1718

1819
pub fn put_all<'info>(
1920
ctx: Context<'_, '_, '_, 'info, PutAll<'info>>,
@@ -39,17 +40,23 @@ pub fn put_all<'info>(
3940
&crate::ID,
4041
);
4142
require_keys_eq!(accumulator_input_ai.key(), pda);
42-
let signer_seeds = &[
43+
let signer_seeds = [
4344
cpi_caller.as_ref(),
4445
ACCUMULATOR.as_ref(),
4546
base_account_key.as_ref(),
4647
&[bump],
4748
];
49+
let fund_pda_bump = *ctx
50+
.bumps
51+
.get("fund")
52+
.ok_or(AccumulatorUpdaterError::FundBumpNotFound)?;
53+
let fund_signer_seeds = [ACCUMULATOR.as_ref(), FUND.as_ref(), &[fund_pda_bump]];
4854
PutAll::create_account(
4955
accumulator_input_ai,
5056
8 + AccumulatorInput::INIT_SPACE,
51-
&ctx.accounts.payer,
52-
signer_seeds,
57+
&ctx.accounts.fund,
58+
// seeds,
59+
&[signer_seeds.as_slice(), fund_signer_seeds.as_slice()],
5360
&ctx.accounts.system_program,
5461
)?;
5562
loader = AccountLoader::<AccumulatorInput>::try_from_unchecked(
@@ -86,22 +93,35 @@ pub fn is_uninitialized_account(ai: &AccountInfo) -> bool {
8693
ai.data_is_empty() && ai.owner == &system_program::ID
8794
}
8895

96+
8997
#[derive(Accounts)]
9098
#[instruction( base_account_key: Pubkey)]
9199
pub struct PutAll<'info> {
92-
#[account(mut)]
93-
pub payer: Signer<'info>,
100+
/// `Fund` is a system account that holds
101+
/// the lamports that will be used to fund
102+
/// `AccumulatorInput` account initialization
103+
#[account(
104+
mut,
105+
seeds = [
106+
b"accumulator".as_ref(),
107+
b"fund".as_ref(),
108+
],
109+
owner = system_program::System::id(),
110+
bump,
111+
)]
112+
pub fund: SystemAccount<'info>,
94113
pub whitelist_verifier: WhitelistVerifier<'info>,
95114
pub system_program: Program<'info, System>,
96115
// remaining_accounts: - [AccumulatorInput PDA]
97116
}
98117

118+
99119
impl<'info> PutAll<'info> {
100120
fn create_account<'a>(
101121
account_info: &AccountInfo<'a>,
102122
space: usize,
103123
payer: &AccountInfo<'a>,
104-
seeds: &[&[u8]],
124+
seeds: &[&[&[u8]]],
105125
system_program: &AccountInfo<'a>,
106126
) -> Result<()> {
107127
let lamports = Rent::get()?.minimum_balance(space);
@@ -113,7 +133,7 @@ impl<'info> PutAll<'info> {
113133
from: payer.to_account_info(),
114134
to: account_info.to_account_info(),
115135
},
116-
&[seeds],
136+
seeds,
117137
),
118138
lamports,
119139
space.try_into().unwrap(),

accumulator_updater/programs/accumulator_updater/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ pub mod accumulator_updater {
8888
#[derive(Accounts)]
8989
pub struct Initialize<'info> {
9090
#[account(mut)]
91-
pub payer: Signer<'info>,
92-
91+
pub payer: Signer<'info>,
9392
#[account(
9493
init,
9594
payer = payer,
@@ -142,4 +141,6 @@ pub enum AccumulatorUpdaterError {
142141
AccumulatorInputNotWritable,
143142
#[msg("Accumulator Input not provided")]
144143
AccumulatorInputNotProvided,
144+
#[msg("Fund Bump not found")]
145+
FundBumpNotFound,
145146
}

accumulator_updater/programs/accumulator_updater/src/state/accumulator_input.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use {
66
anchor_lang::prelude::*,
77
};
88

9+
910
/// `AccumulatorInput` is an arbitrary set of bytes
1011
/// that will be included in the AccumulatorSysvar
1112
///
@@ -42,6 +43,7 @@ pub struct AccumulatorHeader {
4243
pub end_offsets: [u16; 255], // 510
4344
}
4445

46+
4547
impl AccumulatorHeader {
4648
// HEADER_LEN allows for append-only forward-compatibility for the header.
4749
// this is the number of bytes from the beginning of the account_info.data

accumulator_updater/programs/mock-cpi-caller/src/instructions/add_price.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'info> AddPrice<'info> {
6161
inputs: Vec<Vec<u8>>,
6262
) -> anchor_lang::Result<()> {
6363
let mut accounts = vec![
64-
AccountMeta::new(ctx.accounts.payer.key(), true),
64+
AccountMeta::new(ctx.accounts.fund.key(), false),
6565
AccountMeta::new_readonly(ctx.accounts.accumulator_whitelist.key(), false),
6666
AccountMeta::new_readonly(ctx.accounts.ixs_sysvar.key(), false),
6767
AccountMeta::new_readonly(ctx.accounts.system_program.key(), false),
@@ -113,6 +113,8 @@ pub struct AddPrice<'info> {
113113
pub pyth_price_account: AccountLoader<'info, PriceAccount>,
114114
#[account(mut)]
115115
pub payer: Signer<'info>,
116+
#[account(mut)]
117+
pub fund: SystemAccount<'info>,
116118
/// also needed for accumulator_updater
117119
pub system_program: Program<'info, System>,
118120
/// CHECK: whitelist

accumulator_updater/programs/mock-cpi-caller/src/instructions/update_price.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ pub struct UpdatePrice<'info> {
4545
bump,
4646
)]
4747
pub pyth_price_account: AccountLoader<'info, PriceAccount>,
48+
// #[account(mut)]
49+
// pub payer: Signer<'info>,
4850
#[account(mut)]
49-
pub payer: Signer<'info>,
51+
pub fund: SystemAccount<'info>,
5052
/// Needed for accumulator_updater
5153
pub system_program: Program<'info, System>,
5254
/// CHECK: whitelist
@@ -91,7 +93,7 @@ impl<'info> UpdatePrice<'info> {
9193
values: Vec<Vec<u8>>,
9294
) -> anchor_lang::Result<()> {
9395
let mut accounts = vec![
94-
AccountMeta::new(ctx.accounts.payer.key(), true),
96+
AccountMeta::new(ctx.accounts.fund.key(), false),
9597
AccountMeta::new_readonly(ctx.accounts.accumulator_whitelist.key(), false),
9698
AccountMeta::new_readonly(ctx.accounts.ixs_sysvar.key(), false),
9799
AccountMeta::new_readonly(ctx.accounts.system_program.key(), false),

accumulator_updater/tests/accumulator_updater.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const accumulatorUpdaterProgram = anchor.workspace
1515
.AccumulatorUpdater as Program<AccumulatorUpdater>;
1616
const mockCpiProg = anchor.workspace.MockCpiCaller as Program<MockCpiCaller>;
1717
let whitelistAuthority = anchor.web3.Keypair.generate();
18+
const [fundPda] = anchor.web3.PublicKey.findProgramAddressSync(
19+
[Buffer.from("accumulator"), Buffer.from("fund")],
20+
accumulatorUpdaterProgram.programId
21+
);
1822

1923
const pythPriceAccountId = new anchor.BN(1);
2024
const addPriceParams = {
@@ -33,6 +37,7 @@ const [pythPriceAccountPk] = anchor.web3.PublicKey.findProgramAddressSync(
3337
mockCpiProg.programId
3438
);
3539

40+
let fundBalance = 100 * anchor.web3.LAMPORTS_PER_SOL;
3641
describe("accumulator_updater", () => {
3742
// Configure the client to use the local cluster.
3843
let provider = anchor.AnchorProvider.env();
@@ -44,6 +49,10 @@ describe("accumulator_updater", () => {
4449
accumulatorUpdaterProgram.programId
4550
);
4651

52+
before("transfer lamports to the fund", async () => {
53+
await provider.connection.requestAirdrop(fundPda, fundBalance);
54+
});
55+
4756
it("Is initialized!", async () => {
4857
// Add your test here.
4958
const tx = await accumulatorUpdaterProgram.methods
@@ -104,6 +113,7 @@ describe("accumulator_updater", () => {
104113
const mockCpiCallerAddPriceTxPubkeys = await mockCpiProg.methods
105114
.addPrice(addPriceParams)
106115
.accounts({
116+
fund: fundPda,
107117
systemProgram: anchor.web3.SystemProgram.programId,
108118
ixsSysvar: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
109119
accumulatorWhitelist: whitelistPubkey,
@@ -219,6 +229,9 @@ describe("accumulator_updater", () => {
219229
accumulatorAccounts
220230
.map((a) => a.toString())
221231
.includes(accumulatorPdaKey.toString());
232+
233+
const fundBalanceAfter = await provider.connection.getBalance(fundPda);
234+
assert.isTrue(fundBalance > fundBalanceAfter);
222235
});
223236

224237
it("Mock CPI Program - UpdatePrice", async () => {
@@ -233,6 +246,7 @@ describe("accumulator_updater", () => {
233246
await mockCpiProg.methods
234247
.updatePrice(updatePriceParams)
235248
.accounts({
249+
fund: fundPda,
236250
pythPriceAccount: pythPriceAccountPk,
237251
ixsSysvar: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
238252
accumulatorWhitelist: whitelistPubkey,

0 commit comments

Comments
 (0)