Skip to content

Commit cdf3980

Browse files
authored
Merge pull request #169 from buffalojoec/core-bpf-conformance
core-bpf: feature-flag conformance special-casing
2 parents 978dc75 + 3f0fe45 commit cdf3980

File tree

4 files changed

+21
-21
lines changed

4 files changed

+21
-21
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,8 @@ solana-zk-token-sdk = { git = "https://github.com/firedancer-io/agave", rev = "f
5555
# This feature is used to compile a target with a builtin replaced by a BPF program.
5656
# Requires the `CORE_BPF_PROGRAM_ID` and `CORE_BPF_TARGET` environment variables.
5757
core-bpf = []
58+
# Same as the `core-bpf` feature, but also includes special-casing required for
59+
# conformance testing a BPF program against a builtin.
60+
core-bpf-conformance = []
5861
# This feature is used to stub out certain parts of the agave runtime for fuzzing
5962
stub-agave = ["solana-program-runtime/stub-proc-instr"]

macro/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,17 @@ pub fn declare_core_bpf_default_compute_units(_: TokenStream) -> TokenStream {
106106

107107
if program_id == solana_sdk::address_lookup_table::program::id() {
108108
tokens = quote! {
109-
#[cfg(feature = "core-bpf")]
109+
#[cfg(feature = "core-bpf-conformance")]
110110
const CORE_BPF_DEFAULT_COMPUTE_UNITS: u64 = solana_address_lookup_table_program::processor::DEFAULT_COMPUTE_UNITS;
111111
}
112112
} else if program_id == solana_sdk::config::program::id() {
113113
tokens = quote! {
114-
#[cfg(feature = "core-bpf")]
114+
#[cfg(feature = "core-bpf-conformance")]
115115
const CORE_BPF_DEFAULT_COMPUTE_UNITS: u64 = solana_config_program::config_processor::DEFAULT_COMPUTE_UNITS;
116116
}
117117
} else if program_id == solana_sdk::stake::program::id() {
118118
tokens = quote! {
119-
#[cfg(feature = "core-bpf")]
119+
#[cfg(feature = "core-bpf-conformance")]
120120
const CORE_BPF_DEFAULT_COMPUTE_UNITS: u64 = solana_stake_program::stake_instruction::DEFAULT_COMPUTE_UNITS;
121121
}
122122
}

scripts/build_core_bpf.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ set_core_bpf_vars "$1"
3333

3434
CORE_BPF_PROGRAM_ID=$CORE_BPF_PROGRAM_ID CORE_BPF_TARGET=$CORE_BPF_TARGET FORCE_RECOMPILE=true $CARGO build \
3535
--target x86_64-unknown-linux-gnu \
36-
--features core-bpf \
36+
--features core-bpf-conformance \
3737
--lib \
3838
--release

src/lib.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,8 @@ use std::ffi::c_int;
5050
use std::sync::Arc;
5151
use thiserror::Error;
5252

53-
#[cfg(feature = "core-bpf")]
54-
use {
55-
solana_sdk::account::WritableAccount, solana_sdk::slot_hashes::SlotHashes,
56-
solana_sdk::sysvar::Sysvar,
57-
};
53+
#[cfg(any(feature = "core-bpf", feature = "core-bpf-conformance"))]
54+
use solana_sdk::{account::WritableAccount, slot_hashes::SlotHashes, sysvar::Sysvar};
5855

5956
// macro to rewrite &[IDENTIFIER, ...] to &[feature_u64(IDENTIFIER::id()), ...]
6057
#[macro_export]
@@ -579,7 +576,7 @@ fn load_builtins(cache: &mut ProgramCacheForTxBatch) -> HashSet<Pubkey> {
579576
}
580577

581578
fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
582-
#[cfg(feature = "core-bpf")]
579+
#[cfg(feature = "core-bpf-conformance")]
583580
// If the fixture declares `cu_avail` to be less than the builtin version's
584581
// `DEFAULT_COMPUTE_UNITS`, the program should fail on compute meter
585582
// exhaustion.
@@ -595,7 +592,7 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
595592
}
596593
budget
597594
};
598-
#[cfg(not(feature = "core-bpf"))]
595+
#[cfg(not(feature = "core-bpf-conformance"))]
599596
let compute_budget = ComputeBudget {
600597
compute_unit_limit: input.cu_avail,
601598
..ComputeBudget::default()
@@ -607,7 +604,7 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
607604
sysvar_cache.fill_missing_entries(|pubkey, callbackback| {
608605
if let Some(account) = input.accounts.iter().find(|(key, _)| key == pubkey) {
609606
if account.1.lamports > 0 {
610-
#[cfg(feature = "core-bpf")]
607+
#[cfg(any(feature = "core-bpf", feature = "core-bpf-conformance"))]
611608
// BPF versions of programs, such as Address Lookup Table, rely
612609
// on the new `SolGetSysvar` syscall. However, APIs for
613610
// querying slot hashes built on top of `SolGetSysvar` are
@@ -679,7 +676,7 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
679676
.accounts
680677
.iter()
681678
.map(|(pubkey, account)| {
682-
#[cfg(feature = "core-bpf")]
679+
#[cfg(any(feature = "core-bpf", feature = "core-bpf-conformance"))]
683680
// Fixtures provide the program account as a builtin (owned by
684681
// native loader), but the program-runtime will expect the account
685682
// owner to match the cache entry.
@@ -756,7 +753,7 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
756753
let mut newly_loaded_programs = HashSet::<Pubkey>::new();
757754

758755
for acc in &input.accounts {
759-
#[cfg(feature = "core-bpf")]
756+
#[cfg(any(feature = "core-bpf", feature = "core-bpf-conformance"))]
760757
// The Core BPF program's ELF has already been added to the cache.
761758
// Its transaction account was stubbed out, so it can't be loaded via
762759
// callback (inputs), since the account doesn't contain the ELF.
@@ -888,21 +885,21 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
888885
&mut timings,
889886
);
890887

891-
#[cfg(feature = "core-bpf")]
888+
#[cfg(feature = "core-bpf-conformance")]
892889
// To keep alignment with a builtin run, deduct only the CUs the builtin
893890
// version would have consumed, so the fixture realizes the same CU
894891
// deduction across both BPF and builtin in its effects.
895892
let cu_avail = input
896893
.cu_avail
897894
.saturating_sub(CORE_BPF_DEFAULT_COMPUTE_UNITS);
898-
#[cfg(not(feature = "core-bpf"))]
895+
#[cfg(not(feature = "core-bpf-conformance"))]
899896
let cu_avail = input.cu_avail - compute_units_consumed;
900897

901898
let return_data = transaction_context.get_return_data().1.to_vec();
902899

903900
Some(InstrEffects {
904901
custom_err: if let Err(InstructionError::Custom(code)) = result {
905-
#[cfg(feature = "core-bpf")]
902+
#[cfg(feature = "core-bpf-conformance")]
906903
// See comment below under `result` for special-casing of custom
907904
// errors for Core BPF programs.
908905
if program_id == &solana_sdk::address_lookup_table::program::id() && code == 10 {
@@ -912,14 +909,14 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
912909
} else {
913910
Some(code)
914911
}
915-
#[cfg(not(feature = "core-bpf"))]
912+
#[cfg(not(feature = "core-bpf-conformance"))]
916913
Some(code)
917914
} else {
918915
None
919916
},
920917
#[allow(clippy::map_identity)]
921918
result: result.err().map(|err| {
922-
#[cfg(feature = "core-bpf")]
919+
#[cfg(feature = "core-bpf-conformance")]
923920
// Some errors don't directly map between builtins and their BPF
924921
// versions.
925922
//
@@ -944,7 +941,7 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
944941
{
945942
return InstructionError::ComputationalBudgetExceeded;
946943
}
947-
#[cfg(feature = "core-bpf")]
944+
#[cfg(feature = "core-bpf-conformance")]
948945
// Another such error case arises when a program performs a write
949946
// to an account, but the data it writes is the exact same data
950947
// that's currently stored in the account state.
@@ -987,7 +984,7 @@ fn execute_instr(mut input: InstrContext) -> Option<InstrEffects> {
987984
.into_iter()
988985
.enumerate()
989986
.map(|(index, data)| {
990-
#[cfg(feature = "core-bpf")]
987+
#[cfg(any(feature = "core-bpf", feature = "core-bpf-conformance"))]
991988
// Fixtures provide the program account as a builtin account
992989
// (owned by native loader).
993990
//

0 commit comments

Comments
 (0)