Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 64aeae7

Browse files
committed
Rreturn ProgramError from programs
1 parent c350543 commit 64aeae7

21 files changed

+367
-390
lines changed

programs/bpf_loader/src/lib.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use solana_rbpf::{memory_region::MemoryRegion, EbpfVm};
99
use solana_sdk::{
1010
account::KeyedAccount,
1111
entrypoint::SUCCESS,
12-
instruction::InstructionError,
1312
loader_instruction::LoaderInstruction,
13+
program_error::ProgramError,
1414
program_utils::{is_executable, limited_deserialize, next_keyed_account},
1515
pubkey::Pubkey,
1616
sysvar::rent,
@@ -58,7 +58,7 @@ pub fn serialize_parameters(
5858
program_id: &Pubkey,
5959
keyed_accounts: &[KeyedAccount],
6060
data: &[u8],
61-
) -> Result<Vec<u8>, InstructionError> {
61+
) -> Result<Vec<u8>, ProgramError> {
6262
assert_eq!(32, mem::size_of::<Pubkey>());
6363

6464
let mut v: Vec<u8> = Vec::new();
@@ -91,7 +91,7 @@ pub fn serialize_parameters(
9191
pub fn deserialize_parameters(
9292
keyed_accounts: &[KeyedAccount],
9393
buffer: &[u8],
94-
) -> Result<(), InstructionError> {
94+
) -> Result<(), ProgramError> {
9595
assert_eq!(32, mem::size_of::<Pubkey>());
9696

9797
let mut start = mem::size_of::<u64>(); // number of accounts
@@ -122,12 +122,12 @@ pub fn process_instruction(
122122
program_id: &Pubkey,
123123
keyed_accounts: &[KeyedAccount],
124124
instruction_data: &[u8],
125-
) -> Result<(), InstructionError> {
125+
) -> Result<(), ProgramError> {
126126
solana_logger::setup_with_default("solana=info");
127127

128128
if keyed_accounts.is_empty() {
129129
warn!("No account keys");
130-
return Err(InstructionError::NotEnoughAccountKeys);
130+
return Err(ProgramError::NotEnoughAccountKeys);
131131
}
132132

133133
if is_executable(keyed_accounts)? {
@@ -138,7 +138,8 @@ pub fn process_instruction(
138138
Ok(info) => info,
139139
Err(e) => {
140140
warn!("Failed to create BPF VM: {}", e);
141-
return Err(InstructionError::GenericError);
141+
// TODO make these errors bpf enums
142+
return Err(ProgramError::CustomError(0));
142143
}
143144
};
144145
let parameter_accounts = keyed_accounts_iter.as_slice();
@@ -149,14 +150,15 @@ pub fn process_instruction(
149150
match vm.execute_program(parameter_bytes.as_slice(), &[], &[heap_region]) {
150151
Ok(status) => {
151152
if status != SUCCESS {
152-
let error: InstructionError = status.into();
153+
let error: ProgramError = status.into();
153154
warn!("BPF program failed: {:?}", error);
154155
return Err(error);
155156
}
156157
}
157158
Err(e) => {
158159
warn!("BPF VM failed to run program: {}", e);
159-
return Err(InstructionError::GenericError);
160+
// TODO make these errors bpf enums
161+
return Err(ProgramError::CustomError(1));
160162
}
161163
}
162164
deserialize_parameters(parameter_accounts, &parameter_bytes)?;
@@ -168,14 +170,14 @@ pub fn process_instruction(
168170
let program = next_keyed_account(&mut keyed_accounts_iter)?;
169171
if program.signer_key().is_none() {
170172
warn!("key[0] did not sign the transaction");
171-
return Err(InstructionError::MissingRequiredSignature);
173+
return Err(ProgramError::MissingRequiredSignature);
172174
}
173175
let offset = offset as usize;
174176
let len = bytes.len();
175177
trace!("Write: offset={} length={}", offset, len);
176178
if program.data_len()? < offset + len {
177179
warn!("Write overflow: {} < {}", program.data_len()?, offset + len);
178-
return Err(InstructionError::AccountDataTooSmall);
180+
return Err(ProgramError::AccountDataTooSmall);
179181
}
180182
program.try_account_ref_mut()?.data[offset..offset + len].copy_from_slice(&bytes);
181183
}
@@ -186,12 +188,12 @@ pub fn process_instruction(
186188

187189
if program.signer_key().is_none() {
188190
warn!("key[0] did not sign the transaction");
189-
return Err(InstructionError::MissingRequiredSignature);
191+
return Err(ProgramError::MissingRequiredSignature);
190192
}
191193

192194
if let Err(e) = check_elf(&program.try_account_ref()?.data) {
193195
warn!("Invalid ELF: {}", e);
194-
return Err(InstructionError::InvalidAccountData);
196+
return Err(ProgramError::InvalidAccountData);
195197
}
196198

197199
rent::verify_rent_exemption(&program, &rent)?;
@@ -242,13 +244,13 @@ mod tests {
242244

243245
// Case: Empty keyed accounts
244246
assert_eq!(
245-
Err(InstructionError::NotEnoughAccountKeys),
247+
Err(ProgramError::NotEnoughAccountKeys),
246248
process_instruction(&program_id, &vec![], &instruction_data)
247249
);
248250

249251
// Case: Not signed
250252
assert_eq!(
251-
Err(InstructionError::MissingRequiredSignature),
253+
Err(ProgramError::MissingRequiredSignature),
252254
process_instruction(&program_id, &keyed_accounts, &instruction_data)
253255
);
254256

@@ -268,7 +270,7 @@ mod tests {
268270
let mut keyed_accounts = vec![KeyedAccount::new(&program_key, true, &program_account)];
269271
keyed_accounts[0].account.borrow_mut().data = vec![0; 5];
270272
assert_eq!(
271-
Err(InstructionError::AccountDataTooSmall),
273+
Err(ProgramError::AccountDataTooSmall),
272274
process_instruction(&program_id, &keyed_accounts, &instruction_data)
273275
);
274276
}
@@ -289,7 +291,7 @@ mod tests {
289291

290292
// Case: Empty keyed accounts
291293
assert_eq!(
292-
Err(InstructionError::NotEnoughAccountKeys),
294+
Err(ProgramError::NotEnoughAccountKeys),
293295
process_instruction(&program_id, &vec![], &instruction_data)
294296
);
295297

@@ -298,7 +300,7 @@ mod tests {
298300

299301
// Case: Not signed
300302
assert_eq!(
301-
Err(InstructionError::MissingRequiredSignature),
303+
Err(ProgramError::MissingRequiredSignature),
302304
process_instruction(&program_id, &keyed_accounts, &instruction_data)
303305
);
304306

@@ -322,7 +324,7 @@ mod tests {
322324
KeyedAccount::new(&rent_key, false, &rent_account),
323325
];
324326
assert_eq!(
325-
Err(InstructionError::InvalidAccountData),
327+
Err(ProgramError::InvalidAccountData),
326328
process_instruction(&program_id, &keyed_accounts, &instruction_data)
327329
);
328330
}
@@ -346,7 +348,7 @@ mod tests {
346348

347349
// Case: Empty keyed accounts
348350
assert_eq!(
349-
Err(InstructionError::NotEnoughAccountKeys),
351+
Err(ProgramError::NotEnoughAccountKeys),
350352
process_instruction(&program_id, &vec![], &vec![])
351353
);
352354

@@ -359,7 +361,7 @@ mod tests {
359361
// Case: Account not executable
360362
keyed_accounts[0].account.borrow_mut().executable = false;
361363
assert_eq!(
362-
Err(InstructionError::InvalidInstructionData),
364+
Err(ProgramError::InvalidInstructionData),
363365
process_instruction(&program_id, &keyed_accounts, &vec![])
364366
);
365367
keyed_accounts[0].account.borrow_mut().executable = true;

programs/config/src/config_processor.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ use crate::ConfigKeys;
44
use bincode::deserialize;
55
use log::*;
66
use solana_sdk::account::KeyedAccount;
7-
use solana_sdk::instruction::InstructionError;
7+
use solana_sdk::program_error::ProgramError;
88
use solana_sdk::program_utils::{limited_deserialize, next_keyed_account};
99
use solana_sdk::pubkey::Pubkey;
1010

1111
pub fn process_instruction(
1212
_program_id: &Pubkey,
1313
keyed_accounts: &[KeyedAccount],
1414
data: &[u8],
15-
) -> Result<(), InstructionError> {
15+
) -> Result<(), ProgramError> {
1616
let key_list: ConfigKeys = limited_deserialize(data)?;
1717
let keyed_accounts_iter = &mut keyed_accounts.iter();
1818
let config_keyed_account = &mut next_keyed_account(keyed_accounts_iter)?;
@@ -25,7 +25,7 @@ pub fn process_instruction(
2525
config_account.data.len(),
2626
err
2727
);
28-
InstructionError::InvalidAccountData
28+
ProgramError::InvalidAccountData
2929
})?
3030
};
3131
let current_signer_keys: Vec<Pubkey> = current_data
@@ -40,7 +40,7 @@ pub fn process_instruction(
4040
// or when no signers specified in Config data
4141
if config_keyed_account.signer_key().is_none() {
4242
error!("account[0].signer_key().is_none()");
43-
return Err(InstructionError::MissingRequiredSignature);
43+
return Err(ProgramError::MissingRequiredSignature);
4444
}
4545
}
4646

@@ -51,19 +51,19 @@ pub fn process_instruction(
5151
let signer_account = keyed_accounts_iter.next();
5252
if signer_account.is_none() {
5353
error!("account {:?} is not in account list", signer);
54-
return Err(InstructionError::MissingRequiredSignature);
54+
return Err(ProgramError::MissingRequiredSignature);
5555
}
5656
let signer_key = signer_account.unwrap().signer_key();
5757
if signer_key.is_none() {
5858
error!("account {:?} signer_key().is_none()", signer);
59-
return Err(InstructionError::MissingRequiredSignature);
59+
return Err(ProgramError::MissingRequiredSignature);
6060
}
6161
if signer_key.unwrap() != signer {
6262
error!(
6363
"account[{:?}].signer_key() does not match Config data)",
6464
counter + 1
6565
);
66-
return Err(InstructionError::MissingRequiredSignature);
66+
return Err(ProgramError::MissingRequiredSignature);
6767
}
6868
// If Config account is already initialized, update signatures must match Config data
6969
if !current_data.keys.is_empty()
@@ -73,11 +73,11 @@ pub fn process_instruction(
7373
.is_none()
7474
{
7575
error!("account {:?} is not in stored signer list", signer);
76-
return Err(InstructionError::MissingRequiredSignature);
76+
return Err(ProgramError::MissingRequiredSignature);
7777
}
7878
} else if config_keyed_account.signer_key().is_none() {
7979
error!("account[0].signer_key().is_none()");
80-
return Err(InstructionError::MissingRequiredSignature);
80+
return Err(ProgramError::MissingRequiredSignature);
8181
}
8282
}
8383

@@ -88,12 +88,12 @@ pub fn process_instruction(
8888
counter,
8989
current_signer_keys.len()
9090
);
91-
return Err(InstructionError::MissingRequiredSignature);
91+
return Err(ProgramError::MissingRequiredSignature);
9292
}
9393

9494
if config_keyed_account.data_len()? < data.len() {
9595
error!("instruction data too large");
96-
return Err(InstructionError::InvalidInstructionData);
96+
return Err(ProgramError::InvalidInstructionData);
9797
}
9898

9999
config_keyed_account.try_account_ref_mut()?.data[..data.len()].copy_from_slice(&data);
@@ -215,7 +215,7 @@ mod tests {
215215
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
216216
assert_eq!(
217217
process_instruction(&id(), &keyed_accounts, &instruction.data),
218-
Err(InstructionError::InvalidInstructionData)
218+
Err(ProgramError::InvalidInstructionData)
219219
);
220220
}
221221

@@ -233,7 +233,7 @@ mod tests {
233233
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
234234
assert_eq!(
235235
process_instruction(&id(), &keyed_accounts, &instruction.data),
236-
Err(InstructionError::MissingRequiredSignature)
236+
Err(ProgramError::MissingRequiredSignature)
237237
);
238238
}
239239

@@ -290,7 +290,7 @@ mod tests {
290290
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
291291
assert_eq!(
292292
process_instruction(&id(), &keyed_accounts, &instruction.data),
293-
Err(InstructionError::InvalidAccountData)
293+
Err(ProgramError::InvalidAccountData)
294294
);
295295
}
296296

@@ -316,7 +316,7 @@ mod tests {
316316
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
317317
assert_eq!(
318318
process_instruction(&id(), &keyed_accounts, &instruction.data),
319-
Err(InstructionError::MissingRequiredSignature)
319+
Err(ProgramError::MissingRequiredSignature)
320320
);
321321

322322
// Config-data pubkey not a signer
@@ -327,7 +327,7 @@ mod tests {
327327
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
328328
assert_eq!(
329329
process_instruction(&id(), &keyed_accounts, &instruction.data),
330-
Err(InstructionError::MissingRequiredSignature)
330+
Err(ProgramError::MissingRequiredSignature)
331331
);
332332
}
333333

@@ -395,7 +395,7 @@ mod tests {
395395
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
396396
assert_eq!(
397397
process_instruction(&id(), &keyed_accounts, &instruction.data),
398-
Err(InstructionError::MissingRequiredSignature)
398+
Err(ProgramError::MissingRequiredSignature)
399399
);
400400

401401
// Attempt update with incorrect signatures
@@ -414,7 +414,7 @@ mod tests {
414414
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
415415
assert_eq!(
416416
process_instruction(&id(), &keyed_accounts, &instruction.data),
417-
Err(InstructionError::MissingRequiredSignature)
417+
Err(ProgramError::MissingRequiredSignature)
418418
);
419419
}
420420

@@ -477,7 +477,7 @@ mod tests {
477477
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
478478
assert_eq!(
479479
process_instruction(&id(), &keyed_accounts, &instruction.data),
480-
Err(InstructionError::MissingRequiredSignature)
480+
Err(ProgramError::MissingRequiredSignature)
481481
);
482482
}
483483

@@ -491,7 +491,7 @@ mod tests {
491491
let keyed_accounts = create_keyed_is_signer_accounts(&accounts);
492492
assert_eq!(
493493
process_instruction(&id(), &keyed_accounts, &instructions[1].data),
494-
Err(InstructionError::NotEnoughAccountKeys)
494+
Err(ProgramError::NotEnoughAccountKeys)
495495
);
496496
}
497497
}

programs/stake/src/config.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use solana_config_program::{create_config_account, get_config_data, ConfigState}
66
use solana_sdk::{
77
account::{Account, KeyedAccount},
88
genesis_config::GenesisConfig,
9-
instruction::InstructionError,
9+
program_error::ProgramError,
1010
};
1111

1212
// stake config ID
@@ -63,11 +63,11 @@ pub fn create_account(lamports: u64, config: &Config) -> Account {
6363
create_config_account(vec![], config, lamports)
6464
}
6565

66-
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Config, InstructionError> {
66+
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Config, ProgramError> {
6767
if !check_id(account.unsigned_key()) {
68-
return Err(InstructionError::InvalidArgument);
68+
return Err(ProgramError::InvalidArgument);
6969
}
70-
Config::from(&*account.try_account_ref()?).ok_or(InstructionError::InvalidArgument)
70+
Config::from(&*account.try_account_ref()?).ok_or(ProgramError::InvalidArgument)
7171
}
7272

7373
#[cfg(test)]
@@ -82,7 +82,7 @@ mod tests {
8282
assert_eq!(Config::from(&account.borrow()), Some(Config::default()));
8383
assert_eq!(
8484
from_keyed_account(&KeyedAccount::new(&Pubkey::default(), false, &mut account)),
85-
Err(InstructionError::InvalidArgument)
85+
Err(ProgramError::InvalidArgument)
8686
);
8787
}
8888
}

0 commit comments

Comments
 (0)