Skip to content

Commit 5b74c81

Browse files
committed
fix account ordering
1 parent cd0e330 commit 5b74c81

2 files changed

Lines changed: 23 additions & 21 deletions

File tree

smartcontract/programs/doublezero-geolocation/src/processors/geolocation_user/set_result_destination.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ use crate::{
66
};
77
use borsh::{BorshDeserialize, BorshSerialize};
88
use solana_program::{
9-
account_info::{next_account_info, AccountInfo},
10-
entrypoint::ProgramResult,
11-
msg,
12-
program_error::ProgramError,
9+
account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError,
1310
pubkey::Pubkey,
1411
};
1512
use std::{collections::HashSet, net::Ipv4Addr};
@@ -82,11 +79,17 @@ pub fn process_set_result_destination(
8279
accounts: &[AccountInfo],
8380
args: &SetResultDestinationArgs,
8481
) -> ProgramResult {
85-
let accounts_iter = &mut accounts.iter();
86-
87-
let user_account = next_account_info(accounts_iter)?;
88-
let payer_account = next_account_info(accounts_iter)?;
89-
let _system_program = next_account_info(accounts_iter)?;
82+
if accounts.len() < 3 {
83+
msg!("Not enough accounts");
84+
return Err(ProgramError::NotEnoughAccountKeys);
85+
}
86+
// Account layout: [user, probe_0..probe_N, payer, system_program]
87+
// Payer and system_program are always the last two accounts (appended by
88+
// execute_transaction in the SDK), with variable-length probe accounts
89+
// between the user and the payer.
90+
let user_account = &accounts[0];
91+
let payer_account = &accounts[accounts.len() - 2];
92+
let probe_accounts = &accounts[1..accounts.len() - 2];
9093

9194
if !payer_account.is_signer {
9295
msg!("Payer must be a signer");
@@ -124,18 +127,16 @@ pub fn process_set_result_destination(
124127
}
125128
}
126129

127-
// Remaining accounts are the probe accounts to bump target_update_count on.
128-
let remaining: Vec<&AccountInfo> = accounts_iter.collect();
129-
if remaining.len() != unique_probes.len() {
130+
if probe_accounts.len() != unique_probes.len() {
130131
msg!(
131132
"Expected {} probe accounts, got {}",
132133
unique_probes.len(),
133-
remaining.len()
134+
probe_accounts.len()
134135
);
135136
return Err(GeolocationError::TooManyReferencedProbes.into());
136137
}
137138

138-
for probe_account in &remaining {
139+
for probe_account in probe_accounts {
139140
if probe_account.owner != program_id {
140141
msg!("Invalid GeoProbe account owner");
141142
return Err(ProgramError::IllegalOwner);
@@ -155,8 +156,8 @@ pub fn process_set_result_destination(
155156

156157
try_acc_write(&user, user_account, payer_account, accounts)?;
157158

158-
for probe_account in &remaining {
159-
let mut probe = GeoProbe::try_from(*probe_account)?;
159+
for probe_account in probe_accounts {
160+
let mut probe = GeoProbe::try_from(probe_account)?;
160161
probe.target_update_count = probe.target_update_count.wrapping_add(1); // Probe uses change in this value to check for updates.
161162
try_acc_write(&probe, probe_account, payer_account, accounts)?;
162163
}

smartcontract/programs/doublezero-geolocation/tests/geolocation_user_test.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,14 +1463,15 @@ fn build_set_result_destination_ix(
14631463
probe_pdas: &[Pubkey],
14641464
args: SetResultDestinationArgs,
14651465
) -> Instruction {
1466-
let mut accounts = vec![
1467-
AccountMeta::new(*user_pda, false),
1468-
AccountMeta::new(*payer, true),
1469-
AccountMeta::new_readonly(solana_program::system_program::id(), false),
1470-
];
1466+
let mut accounts = vec![AccountMeta::new(*user_pda, false)];
14711467
for probe_pda in probe_pdas {
14721468
accounts.push(AccountMeta::new(*probe_pda, false));
14731469
}
1470+
accounts.push(AccountMeta::new(*payer, true));
1471+
accounts.push(AccountMeta::new_readonly(
1472+
solana_program::system_program::id(),
1473+
false,
1474+
));
14741475
Instruction::new_with_borsh(
14751476
*program_id,
14761477
&GeolocationInstruction::SetResultDestination(args),

0 commit comments

Comments
 (0)