Skip to content

Commit c3d59a5

Browse files
LucasStemergify[bot]
authored andcommitted
Add SBPFv1 tests to the CI pipeline (#5126)
* Add SBPFv1 to the CI pipeline * Tune instruction count * Check upper bound instead of fixed number of instructions * Verify zeroed stack with dynamic stack frames * Use constants to estimate length of zeroed bytes * Remove comment (cherry picked from commit b704875) # Conflicts: # programs/sbf/tests/programs.rs
1 parent 7aff93a commit c3d59a5

File tree

5 files changed

+80
-6
lines changed

5 files changed

+80
-6
lines changed

ci/test-stable.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@ test-stable-sbf)
5555
# Install the platform tools
5656
_ platform-tools-sdk/sbf/scripts/install.sh
5757

58-
# SBF program tests
58+
# SBPFv0 program tests
5959
_ make -C programs/sbf test-v0
6060

61+
# SBPFv1 program tests
62+
_ make -C programs/sbf clean-all test-v1
63+
6164
exit 0
6265
;;
6366
test-docs)

programs/sbf/Makefile

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,27 @@ SBF_SDK_PATH := ../../platform-tools-sdk/sbf
22
SRC_DIR := c/src
33
OUT_DIR := target/deploy
44

5-
test-v0: all rust-v0
5+
clean-all: clean
6+
cargo clean
7+
8+
test:
69
SBF_OUT_DIR=$(OUT_DIR) cargo test --features="sbf_rust,sbf_c" $(TEST_ARGS)
710

11+
test-v1:
12+
SBPF_CPU=v1 $(MAKE) all ; \
13+
$(MAKE) rust-v1 ; \
14+
$(MAKE) test
15+
16+
test-v0: all rust-v0 test
17+
818
rust-v0:
919
cargo +solana build --release --target sbpf-solana-solana --workspace ; \
1020
cp -r target/sbpf-solana-solana/release/* target/deploy
1121

12-
.PHONY: rust
22+
rust-v1:
23+
cargo +solana build --release --target sbpfv1-solana-solana --workspace --features dynamic-frames ; \
24+
cp -r target/sbpfv1-solana-solana/release/* target/deploy
25+
26+
.PHONY: rust-v0
1327

1428
include $(SBF_SDK_PATH)/c/sbf.mk

programs/sbf/rust/invoke/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ crate-type = ["cdylib"]
1919

2020
[lints]
2121
workspace = true
22+
23+
[features]
24+
dynamic-frames = []

programs/sbf/rust/invoke/src/lib.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#![allow(unreachable_code)]
44
#![allow(clippy::arithmetic_side_effects)]
55

6+
#[cfg(feature = "dynamic-frames")]
7+
use solana_program::program_memory::sol_memcmp;
68
use {
79
solana_program::{
810
account_info::AccountInfo,
@@ -1456,19 +1458,36 @@ fn process_instruction<'a>(
14561458
heap[8..pos].fill(42);
14571459

14581460
// Check that the stack is zeroed too.
1459-
//
1461+
let stack = unsafe {
1462+
slice::from_raw_parts_mut(
1463+
MM_STACK_START as *mut u8,
1464+
MAX_CALL_DEPTH * STACK_FRAME_SIZE,
1465+
)
1466+
};
1467+
1468+
#[cfg(not(feature = "dynamic-frames"))]
14601469
// We don't know in which frame we are now, so we skip a few (10) frames at the start
14611470
// which might have been used by the current call stack. We check that the memory for
14621471
// the 10..MAX_CALL_DEPTH frames is zeroed. Then we write a sentinel value, and in the
14631472
// next nested invocation check that it's been zeroed.
1464-
let stack =
1465-
unsafe { slice::from_raw_parts_mut(MM_STACK_START as *mut u8, 0x100000000) };
1473+
//
1474+
// When we don't have dynamic stack frames, the stack grows from lower addresses
1475+
// to higher addresses, so we compare accordingly.
14661476
for i in 10..MAX_CALL_DEPTH {
14671477
let stack = &mut stack[i * STACK_FRAME_SIZE..][..STACK_FRAME_SIZE];
14681478
assert!(stack == &ZEROS[..STACK_FRAME_SIZE], "stack not zeroed");
14691479
stack.fill(42);
14701480
}
14711481

1482+
#[cfg(feature = "dynamic-frames")]
1483+
// When we have dynamic frames, the stack grows from the higher addresses, so we
1484+
// compare from zero until the beginning of a function frame.
1485+
{
1486+
const ZEROED_BYTES_LENGTH: usize = (MAX_CALL_DEPTH - 2) * STACK_FRAME_SIZE;
1487+
assert_eq!(sol_memcmp(stack, &ZEROS, ZEROED_BYTES_LENGTH), 0);
1488+
stack[..ZEROED_BYTES_LENGTH].fill(42);
1489+
}
1490+
14721491
// Recurse to check that the stack and heap are zeroed.
14731492
//
14741493
// We recurse until we go over max CPI depth and error out. Stack and heap allocations

programs/sbf/tests/programs.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,7 @@ fn assert_instruction_count() {
12661266
#[cfg(feature = "sbf_c")]
12671267
{
12681268
programs.extend_from_slice(&[
1269+
<<<<<<< HEAD
12691270
("alloc", 19332),
12701271
("sbf_to_sbf", 316),
12711272
("multiple_static", 210),
@@ -1277,13 +1278,27 @@ fn assert_instruction_count() {
12771278
("sanity++", 2296),
12781279
("secp256k1_recover", 25483),
12791280
("sha", 1447),
1281+
=======
1282+
("alloc", 14575),
1283+
("sbf_to_sbf", 313),
1284+
("multiple_static", 208),
1285+
("noop", 5),
1286+
("noop++", 5),
1287+
("relative_call", 210),
1288+
("return_data", 982),
1289+
("sanity", 2377),
1290+
("sanity++", 2277),
1291+
("secp256k1_recover", 25483),
1292+
("sha", 1355),
1293+
>>>>>>> b704875fb (Add SBPFv1 tests to the CI pipeline (#5126))
12801294
("struct_pass", 108),
12811295
("struct_ret", 122),
12821296
]);
12831297
}
12841298
#[cfg(feature = "sbf_rust")]
12851299
{
12861300
programs.extend_from_slice(&[
1301+
<<<<<<< HEAD
12871302
("solana_sbf_rust_128bit", 969),
12881303
("solana_sbf_rust_alloc", 5077),
12891304
("solana_sbf_rust_custom_heap", 304),
@@ -1298,6 +1313,22 @@ fn assert_instruction_count() {
12981313
("solana_sbf_rust_sanity", 51325),
12991314
("solana_sbf_rust_secp256k1_recover", 89388),
13001315
("solana_sbf_rust_sha", 22855),
1316+
=======
1317+
("solana_sbf_rust_128bit", 955),
1318+
("solana_sbf_rust_alloc", 4784),
1319+
("solana_sbf_rust_custom_heap", 270),
1320+
("solana_sbf_rust_dep_crate", 2),
1321+
("solana_sbf_rust_iter", 1514),
1322+
("solana_sbf_rust_many_args", 1289),
1323+
("solana_sbf_rust_mem", 1207),
1324+
("solana_sbf_rust_membuiltins", 292),
1325+
("solana_sbf_rust_noop", 275),
1326+
("solana_sbf_rust_param_passing", 108),
1327+
("solana_sbf_rust_rand", 264),
1328+
("solana_sbf_rust_sanity", 50084),
1329+
("solana_sbf_rust_secp256k1_recover", 89217),
1330+
("solana_sbf_rust_sha", 22850),
1331+
>>>>>>> b704875fb (Add SBPFv1 tests to the CI pipeline (#5126))
13011332
]);
13021333
}
13031334

@@ -1698,7 +1729,11 @@ fn test_program_sbf_invoke_in_same_tx_as_deployment() {
16981729
// Asserting the instruction number as an upper bound, since the quantity of
16991730
// instructions depends on the program size, which in turn depends on the SBPF
17001731
// versions.
1732+
<<<<<<< HEAD
17011733
assert!(instr_no <= 41);
1734+
=======
1735+
assert!(instr_no <= 38);
1736+
>>>>>>> b704875fb (Add SBPFv1 tests to the CI pipeline (#5126))
17021737
assert_eq!(ty, InstructionError::UnsupportedProgramId);
17031738
} else {
17041739
panic!("Invalid error type");

0 commit comments

Comments
 (0)