Skip to content

Commit 9f33632

Browse files
committed
core-bpf: special-case core bpf program error codes
1 parent 9d7f75b commit 9f33632

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

src/lib.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,19 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
872872
let return_data = transaction_context.get_return_data().1.to_vec();
873873

874874
Some(InstrEffects {
875-
custom_err: if let Err(InstructionError::Custom(x)) = result {
876-
Some(x)
875+
custom_err: if let Err(InstructionError::Custom(code)) = result {
876+
#[cfg(feature = "core-bpf")]
877+
// See comment below under `result` for special-casing of custom
878+
// errors for Core BPF programs.
879+
if program_id == &solana_sdk::address_lookup_table::program::id() && code == 10 {
880+
None
881+
} else if program_id == &solana_sdk::config::program::id() && code == 0 {
882+
None
883+
} else {
884+
Some(code)
885+
}
886+
#[cfg(not(feature = "core-bpf"))]
887+
Some(code)
877888
} else {
878889
None
879890
},
@@ -904,6 +915,41 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
904915
{
905916
return InstructionError::ComputationalBudgetExceeded;
906917
}
918+
#[cfg(feature = "core-bpf")]
919+
// Another such error case arises when a program performs a write
920+
// to an account, but the data it writes is the exact same data
921+
// that's currently stored in the account state.
922+
//
923+
// For builtins, the `TransactionContext` is invoked when any write
924+
// is performed, asking it whether or not a write is allowed,
925+
// regardless of the data being written. If the account is not
926+
// writable, it throws `InstructionError::ReadonlyDataModified`.
927+
//
928+
// For BPF programs, writes to readonly accounts are caught _after_
929+
// the VM finishes execution, when the loader inspects the
930+
// serialized input data region. If a write was performed that did
931+
// not modify serialized account state, then no error is thrown.
932+
//
933+
// As a result, Core BPF programs have been outfitted with custom
934+
// errors when `is_writable` checks fail. These errors are
935+
// special-cased below to avoid fixture mismatches.
936+
match err {
937+
InstructionError::Custom(code) => {
938+
if program_id == &solana_sdk::address_lookup_table::program::id() {
939+
// Special-cased custom error codes for the ALT program.
940+
if code == 10 {
941+
return InstructionError::ReadonlyDataModified;
942+
}
943+
}
944+
if program_id == &solana_sdk::config::program::id() {
945+
// Special-cased custom error codes for the Config program.
946+
if code == 0 {
947+
return InstructionError::ReadonlyDataModified;
948+
}
949+
}
950+
}
951+
_ => {}
952+
}
907953
err
908954
}),
909955
modified_accounts: transaction_context

0 commit comments

Comments
 (0)