Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"accounts-bench",
"accounts-cluster-bench",
"banking-bench",
"banking-bench2",
"banks-client",
"banks-interface",
"banks-server",
Expand Down Expand Up @@ -294,6 +295,7 @@ soketto = "0.7"
solana_rbpf = "=0.5.0"
solana-account-decoder = { path = "account-decoder", version = "=1.17.0" }
solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.0" }
solana-banking-bench = { path = "banking-bench", version = "=1.17.0" }
solana-banks-client = { path = "banks-client", version = "=1.17.0" }
solana-banks-interface = { path = "banks-interface", version = "=1.17.0" }
solana-banks-server = { path = "banks-server", version = "=1.17.0" }
Expand Down
8 changes: 7 additions & 1 deletion banking-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ solana-measure = { workspace = true }
solana-perf = { workspace = true }
solana-poh = { workspace = true }
solana-runtime = { workspace = true }
solana-sdk = { workspace = true }
solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
solana-streamer = { workspace = true }
solana-tpu-client = { workspace = true }
solana-version = { workspace = true }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[features]
dev-context-only-utils = []

[lib]
crate-type = ["cdylib", "rlib"]
1 change: 1 addition & 0 deletions banking-bench/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

18 changes: 18 additions & 0 deletions banking-bench2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "solana-banking-bench2"
publish = false
version = { workspace = true }
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }

[dependencies]
solana-banking-bench = { workspace = true, features = ["dev-context-only-utils"] }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[features]
dev-context-only-utils = []
1 change: 1 addition & 0 deletions banking-bench2/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn main() {}
4 changes: 3 additions & 1 deletion ci/buildkite-pipeline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ wait_step() {
}

all_test_steps() {
command_step checks ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-checks.sh" 20 check
command_step checks1 ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-checks.sh" 20 check
command_step checks2 ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-dev-context-only-utils.sh check-bins" 15 check
command_step checks3 ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-dev-context-only-utils.sh check-all-targets" 15 check
wait_step

# Full test suite
Expand Down
4 changes: 4 additions & 0 deletions ci/test-checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ echo --- build environment
cargo clippy --version --verbose
$cargoNightly clippy --version --verbose

$cargoNightly hack --version --verbose

# audit is done only with "$cargo stable"
cargo audit --version

Expand Down Expand Up @@ -110,6 +112,8 @@ else
_ scripts/cargo-for-all-lock-files.sh -- "+${rust_nightly}" sort --workspace --check
fi

_ scripts/check-dev-context-only-utils.sh tree

_ scripts/cargo-for-all-lock-files.sh -- "+${rust_nightly}" fmt --all -- --check

_ ci/do-audit.sh
Expand Down
5 changes: 5 additions & 0 deletions ci/test-dev-context-only-utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

set -eo pipefail

scripts/check-dev-context-only-utils.sh "$@"
2 changes: 1 addition & 1 deletion poh-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ solana-entry = { workspace = true }
solana-logger = { workspace = true }
solana-measure = { workspace = true }
solana-perf = { workspace = true }
solana-sdk = { workspace = true }
solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
solana-version = { workspace = true }

[package.metadata.docs.rs]
Expand Down
155 changes: 155 additions & 0 deletions scripts/check-dev-context-only-utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#!/usr/bin/env bash

set -eo pipefail
cd "$(dirname "$0")/.."
source ci/_
# only nightly is used uniformly as we contain good amount of nightly-only code
# (benches, frozen abi...)
source ci/rust-version.sh nightly

# There's a special common feature called `dev-context-only-utils` to
# overcome cargo's issue: https://github.com/rust-lang/cargo/issues/8379
# This feature is like `cfg(test)`, which works between crates.
#
# Unfortunately, this in turn needs some special checks to avoid common
# pitfalls of `dev-context-only-utils` itself.
#
# Firstly, detect any misuse of dev-context-only-utils as normal/build
# dependencies. Also, allow some exceptions for special purpose crates. This
# white-listing mechanism can be used for core-development-oriented crates like
# bench bins.
#
# Put differently, use of dev-context-only-utils is forbidden for non-dev
# dependencies in general. However, allow its use for non-dev dependencies only
# if its use is confined under a dep. subgraph with all nodes being marked as
# dev-context-only-utils.

# Add your troubled package which seems to want to use `dev-context-only-utils`
# as normal (not dev) dependencies, only if you're sure that there's good
# reason to bend dev-context-only-utils's original intention and that listed
# package isn't part of released binaries.
declare tainted_packages=(
"solana-banking-bench"
"solana-banking-bench2"
"solana-poh-bench"
)

# convert to comma separeted (ref: https://stackoverflow.com/a/53839433)
printf -v allowed '"%s",' "${tainted_packages[@]}"
allowed="${allowed%,}"

mode=${1:-full}
case "$mode" in
tree | check-bins | check-all-targets | full)
;;
*)
echo "$0: unrecognized mode: $mode";
exit 1
;;
esac

if [[ $mode = "tree" || $mode = "full" ]]; then
query=$(cat <<EOF
.packages
| map(.name as \$crate
| (.dependencies
| map(select((.kind // "normal") == "normal"))
| map({
"crate" : \$crate,
"dependency" : .name,
"dependencyFeatures" : .features,
})
)
)
| flatten
| map(select(
(.dependencyFeatures
| index("dev-context-only-utils")
) and (.crate as \$needle
| ([$allowed] | index(\$needle))
| not
)
))
| map([.crate, .dependency] | join(": "))
| join("\n ")
EOF
)

abusers="$(_ cargo "+${rust_nightly}" metadata --format-version=1 |
jq -r "$query")"
if [[ -n "$abusers" ]]; then
cat <<EOF 1>&2
\`dev-context-only-utils\` must not be used as normal dependencies, but is by \
"([crate]: [dependency])":
$abusers
EOF
exit 1
fi

# Sanity-check that tainted packages has undergone the proper tedious rituals
# to be justified as such.
query=$(cat <<EOF
.packages
| map([.name, (.features | keys)] as [\$this_crate, \$this_feature]
| if .name as \$needle | ([$allowed] | index(\$needle))
then
{
"crate": \$this_crate,
"crateFeatures": \$this_feature,
}
elif .dependencies | any(
.name as \$needle | ([$allowed] | index(\$needle))
)
then
.dependencies
| map({
"crate": \$this_crate,
"crateFeatures": \$this_feature,
})
else
[]
end)
| flatten
| map(select(
(.crateFeatures | index("dev-context-only-utils")) | not
))
| map(.crate)
| join("\n ")
EOF
)

misconfigured_crates=$(
_ cargo "+${rust_nightly}" metadata \
--format-version=1 \
| jq -r "$query"
)
if [[ -n "$misconfigured_crates" ]]; then
cat <<EOF 1>&2
All crates marked \`tainted\`, as well as their dependents, MUST declare the \
\`dev-context-only-utils\`. The following crates are in violation:
$misconfigured_crates
EOF
exit 1
fi
fi

# Detect possible compilation errors of problematic usage of
# `dev-context-only-utils`-gated code without being explicitly declared as such
# in respective workspace member `Cargo.toml`s. This cannot be detected with
# `--workspace --all-targets`, due to unintentional `dev-context-only-utils`
# feature activation by cargo's feature unification mechanism. So, we use
# `cargo hack` to exhaustively build each individual workspace members in
# isolation to work around.
#
# 1. Check implicit usage of `dev-context-only-utils`-gated code in non-dev (=
# production) code by building without dev dependencies (= tests/benches) for
# each crate
# 2. Check implicit usage of `dev-context-only-utils`-gated code in dev (=
# test/benches) code by building in isolation from other crates, which might
# happen to enable `dev-context-only-utils`
if [[ $mode = "check-bins" || $mode = "full" ]]; then
_ cargo "+${rust_nightly}" hack check --bins
fi
if [[ $mode = "check-all-targets" || $mode = "full" ]]; then
_ cargo "+${rust_nightly}" hack check --all-targets
fi
1 change: 1 addition & 0 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ full = [
"sha3",
"digest",
]
dev-context-only-utils = []

[dependencies]
assert_matches = { workspace = true, optional = true }
Expand Down