diff --git a/.github/workflows/downstream-project-spl.yml b/.github/workflows/downstream-project-spl.yml
index 017a13ce5b88c7..3d4887cf817804 100644
--- a/.github/workflows/downstream-project-spl.yml
+++ b/.github/workflows/downstream-project-spl.yml
@@ -39,6 +39,7 @@ env:
jobs:
check:
if: github.repository == 'anza-xyz/agave'
+ if: false
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
@@ -77,6 +78,7 @@ jobs:
test_cli:
if: github.repository == 'anza-xyz/agave'
+ if: false
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
@@ -107,6 +109,7 @@ jobs:
cargo-test-sbf:
if: github.repository == 'anza-xyz/agave'
+ if: false
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
@@ -148,7 +151,8 @@ jobs:
run: |
source ci/downstream-projects/common.sh
cd "${{ matrix.programs }}"
- $CARGO_TEST_SBF --arch v0 --manifest-path program/Cargo.toml
+ $CARGO_BUILD_SBF --arch v0 --manifest-path program/Cargo.toml
+ RUSTFLAGS="-Awarnings" SBF_OUT_DIR="../target/deploy" cargo test --features test-sbf --manifest-path program/Cargo.toml
- name: Test SBPFv1
shell: bash
@@ -156,7 +160,8 @@ jobs:
source ci/downstream-projects/common.sh
cd "${{ matrix.programs }}"
rm -rf target/deploy target/sbpf*
- $CARGO_TEST_SBF --arch v1 --manifest-path program/Cargo.toml
+ $CARGO_BUILD_SBF --arch v1 --manifest-path program/Cargo.toml
+ RUSTFLAGS="-Awarnings" SBF_OUT_DIR="../target/deploy" cargo test --features test-sbf --manifest-path program/Cargo.toml
- name: Test SBPFv2
shell: bash
@@ -164,7 +169,8 @@ jobs:
source ci/downstream-projects/common.sh
cd "${{ matrix.programs }}"
rm -rf target/deploy target/sbpf*
- $CARGO_TEST_SBF --arch v2 --manifest-path program/Cargo.toml
+ $CARGO_BUILD_SBF --arch v2 --manifest-path program/Cargo.toml
+ RUSTFLAGS="-Awarnings" SBF_OUT_DIR="../target/deploy" cargo test --features test-sbf --manifest-path program/Cargo.toml
- name: Test SBPFv3
shell: bash
@@ -172,4 +178,5 @@ jobs:
source ci/downstream-projects/common.sh
cd "${{ matrix.programs }}"
rm -rf target/deploy target/sbpf*
- $CARGO_TEST_SBF --arch v3 --manifest-path program/Cargo.toml
+ $CARGO_BUILD_SBF --arch v3 --manifest-path program/Cargo.toml
+ RUSTFLAGS="-Awarnings" SBF_OUT_DIR="../target/deploy" cargo test --features test-sbf --manifest-path program/Cargo.toml
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9d2f180d06b497..2a2cae1184d30c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -47,6 +47,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
+ token: ${{ secrets.VERSION_BUMP_PAT }}
- name: Parse Info
id: parse_info
diff --git a/.github/workflows/svm-exampls.yml b/.github/workflows/svm-examples.yml
similarity index 96%
rename from .github/workflows/svm-exampls.yml
rename to .github/workflows/svm-examples.yml
index 46bbbf3163fbcb..d31007e53b42f8 100644
--- a/.github/workflows/svm-exampls.yml
+++ b/.github/workflows/svm-examples.yml
@@ -44,7 +44,7 @@ jobs:
- name: Run build
run: |
cd svm/examples
- cargo build --tests
+ cargo build
- name: Run tests
run: |
diff --git a/.mergify.yml b/.mergify.yml
index 309f34ed4eb0e9..2ff48f54615b28 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -104,9 +104,9 @@ pull_request_rules:
- automerge
comment:
message: automerge label removed due to a CI failure
- - name: v2.1 feature-gate backport
+ - name: v2.2 feature-gate backport
conditions:
- - label=v2.1
+ - label=v2.2
- label=feature-gate
actions:
backport:
@@ -117,10 +117,10 @@ pull_request_rules:
labels:
- feature-gate
branches:
- - v2.1
- - name: v2.1 non-feature-gate backport
+ - v2.2
+ - name: v2.2 non-feature-gate backport
conditions:
- - label=v2.1
+ - label=v2.2
- label!=feature-gate
actions:
backport:
@@ -128,10 +128,10 @@ pull_request_rules:
title: "{{ destination_branch }}: {{ title }} (backport of #{{ number }})"
ignore_conflicts: true
branches:
- - v2.1
- - name: v2.1 backport warning comment
+ - v2.2
+ - name: v2.2 backport warning comment
conditions:
- - label=v2.1
+ - label=v2.2
actions:
comment:
message: >
@@ -142,9 +142,9 @@ pull_request_rules:
refactoring, plumbing, cleanup, etc that are not strictly
necessary to achieve the goal. Any of the latter should go only
into master and ride the normal stabilization schedule.
- - name: v2.2 feature-gate backport
+ - name: v2.3 feature-gate backport
conditions:
- - label=v2.2
+ - label=v2.3
- label=feature-gate
actions:
backport:
@@ -154,10 +154,10 @@ pull_request_rules:
labels:
- feature-gate
branches:
- - v2.2
- - name: v2.2 non-feature-gate backport
+ - v2.3
+ - name: v2.3 non-feature-gate backport
conditions:
- - label=v2.2
+ - label=v2.3
- label!=feature-gate
actions:
backport:
@@ -165,10 +165,10 @@ pull_request_rules:
title: "{{ destination_branch }}: {{ title }} (backport of #{{ number }})"
ignore_conflicts: true
branches:
- - v2.2
- - name: v2.2 backport warning comment
+ - v2.3
+ - name: v2.3 backport warning comment
conditions:
- - label=v2.2
+ - label=v2.3
actions:
comment:
message: >
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9282b9de03949e..5d7cf2fbbd4fb5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,12 +8,15 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
and follows a [Backwards Compatibility Policy](https://docs.solanalabs.com/backwards-compatibility)
Release channels have their own copy of this changelog:
-* [edge - v2.3](#edge-channel)
-* [beta - v2.2](https://github.com/anza-xyz/agave/blob/v2.2/CHANGELOG.md)
-* [stable - v2.1](https://github.com/anza-xyz/agave/blob/v2.1/CHANGELOG.md)
+* [edge - v3.0](#edge-channel)
+* [beta - v2.3](https://github.com/anza-xyz/agave/blob/v2.3/CHANGELOG.md)
+* [stable - v2.2](https://github.com/anza-xyz/agave/blob/v2.2/CHANGELOG.md)
-## 2.3.0 - Unreleased
+## 3.0.0 - Unreleased
+
+
+## 2.3.0
### Validator
diff --git a/Cargo.lock b/Cargo.lock
index a4b6cb8b28930a..4e13fb284632e9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -77,7 +77,7 @@ dependencies = [
[[package]]
name = "agave-accounts-hash-cache-tool"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"ahash 0.8.11",
"anyhow",
@@ -93,7 +93,7 @@ dependencies = [
[[package]]
name = "agave-banking-stage-ingress-types"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"crossbeam-channel",
"solana-perf",
@@ -101,7 +101,7 @@ dependencies = [
[[package]]
name = "agave-cargo-registry"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 2.33.3",
"flate2",
@@ -133,7 +133,7 @@ dependencies = [
[[package]]
name = "agave-feature-set"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"ahash 0.8.11",
"solana-epoch-schedule",
@@ -147,7 +147,7 @@ dependencies = [
[[package]]
name = "agave-geyser-plugin-interface"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
"solana-clock",
@@ -159,7 +159,7 @@ dependencies = [
[[package]]
name = "agave-install"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"atty",
"bincode",
@@ -172,7 +172,7 @@ dependencies = [
"dirs-next",
"indicatif",
"nix",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"scopeguard",
"semver 1.0.26",
"serde",
@@ -180,6 +180,7 @@ dependencies = [
"serde_yaml 0.8.26",
"serde_yaml 0.9.34+deprecated",
"solana-clap-utils",
+ "solana-config-interface",
"solana-config-program-client",
"solana-hash",
"solana-keypair",
@@ -201,7 +202,7 @@ dependencies = [
[[package]]
name = "agave-ledger-tool"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-reserved-account-keys",
@@ -242,6 +243,7 @@ dependencies = [
"solana-gossip",
"solana-hash",
"solana-inflation",
+ "solana-instruction",
"solana-keypair",
"solana-ledger",
"solana-loader-v3-interface 5.0.0",
@@ -268,7 +270,7 @@ dependencies = [
"solana-svm-feature-set",
"solana-system-interface",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-status",
"solana-type-overrides",
"solana-unified-scheduler-pool",
@@ -282,7 +284,7 @@ dependencies = [
[[package]]
name = "agave-precompiles"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"bincode",
@@ -308,7 +310,7 @@ dependencies = [
[[package]]
name = "agave-reserved-account-keys"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"solana-frozen-abi",
@@ -321,7 +323,7 @@ dependencies = [
[[package]]
name = "agave-store-histogram"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 2.33.3",
"solana-version",
@@ -329,7 +331,7 @@ dependencies = [
[[package]]
name = "agave-store-tool"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"ahash 0.8.11",
"clap 2.33.3",
@@ -343,7 +345,7 @@ dependencies = [
[[package]]
name = "agave-thread-manager"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"affinity",
"agave-thread-manager",
@@ -366,7 +368,7 @@ dependencies = [
[[package]]
name = "agave-transaction-view"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-transaction-view",
"bincode",
@@ -388,7 +390,7 @@ dependencies = [
[[package]]
name = "agave-validator"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-geyser-plugin-interface",
"assert_cmd",
@@ -476,7 +478,7 @@ dependencies = [
[[package]]
name = "agave-watchtower"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 2.33.3",
"humantime",
@@ -497,7 +499,7 @@ dependencies = [
[[package]]
name = "agave-xdp"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"aya",
"caps",
@@ -1019,7 +1021,7 @@ dependencies = [
"http 1.1.0",
"http-body 1.0.1",
"http-body-util",
- "hyper 1.5.1",
+ "hyper 1.6.0",
"hyper-util",
"itoa",
"matchit",
@@ -1180,7 +1182,7 @@ dependencies = [
"bitflags 2.9.1",
"cexpr",
"clang-sys",
- "itertools 0.12.1",
+ "itertools 0.10.5",
"lazy_static",
"lazycell",
"proc-macro2",
@@ -1302,7 +1304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
dependencies = [
"borsh-derive 0.10.3",
- "hashbrown 0.13.2",
+ "hashbrown 0.12.3",
]
[[package]]
@@ -2955,7 +2957,7 @@ dependencies = [
[[package]]
name = "gen-headers"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
"regex",
@@ -2963,7 +2965,7 @@ dependencies = [
[[package]]
name = "gen-syscall-list"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"regex",
]
@@ -3240,6 +3242,12 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+[[package]]
+name = "hermit-abi"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
+
[[package]]
name = "hex"
version = "0.4.3"
@@ -3353,9 +3361,9 @@ dependencies = [
[[package]]
name = "httparse"
-version = "1.8.0"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "httpdate"
@@ -3401,9 +3409,9 @@ dependencies = [
[[package]]
name = "hyper"
-version = "1.5.1"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f"
+checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
@@ -3459,7 +3467,7 @@ checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
dependencies = [
"futures-util",
"http 1.1.0",
- "hyper 1.5.1",
+ "hyper 1.6.0",
"hyper-util",
"rustls 0.23.27",
"rustls-pki-types",
@@ -3496,16 +3504,21 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.10"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
+checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
dependencies = [
+ "base64 0.22.1",
"bytes",
"futures-channel",
+ "futures-core",
"futures-util",
"http 1.1.0",
"http-body 1.0.1",
- "hyper 1.5.1",
+ "hyper 1.6.0",
+ "ipnet",
+ "libc",
+ "percent-encoding 2.3.1",
"pin-project-lite",
"socket2",
"tokio",
@@ -3777,9 +3790,19 @@ dependencies = [
[[package]]
name = "ipnet"
-version = "2.3.1"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+
+[[package]]
+name = "iri-string"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
+dependencies = [
+ "memchr",
+ "serde",
+]
[[package]]
name = "is-terminal"
@@ -4565,11 +4588,11 @@ dependencies = [
[[package]]
name = "num_cpus"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
dependencies = [
- "hermit-abi 0.3.9",
+ "hermit-abi 0.5.1",
"libc",
]
@@ -5237,7 +5260,7 @@ dependencies = [
[[package]]
name = "proto"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"protobuf-src",
"tonic-build",
@@ -5557,7 +5580,7 @@ dependencies = [
[[package]]
name = "rbpf-cli"
-version = "2.3.0"
+version = "3.0.0"
[[package]]
name = "rdrand"
@@ -5673,7 +5696,7 @@ dependencies = [
"percent-encoding 2.3.1",
"pin-project-lite",
"rustls 0.21.12",
- "rustls-pemfile 1.0.0",
+ "rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
@@ -5694,9 +5717,9 @@ dependencies = [
[[package]]
name = "reqwest"
-version = "0.12.15"
+version = "0.12.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
+checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119"
dependencies = [
"async-compression",
"base64 0.22.1",
@@ -5707,7 +5730,7 @@ dependencies = [
"http 1.1.0",
"http-body 1.0.1",
"http-body-util",
- "hyper 1.5.1",
+ "hyper 1.6.0",
"hyper-rustls 0.27.5",
"hyper-util",
"ipnet",
@@ -5719,7 +5742,6 @@ dependencies = [
"pin-project-lite",
"quinn",
"rustls 0.23.27",
- "rustls-pemfile 2.1.3",
"rustls-pki-types",
"serde",
"serde_json",
@@ -5729,13 +5751,13 @@ dependencies = [
"tokio-rustls 0.26.2",
"tokio-util 0.7.15",
"tower 0.5.2",
+ "tower-http",
"tower-service",
"url 2.5.4",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
- "webpki-roots 0.26.8",
- "windows-registry",
+ "webpki-roots 1.0.0",
]
[[package]]
@@ -5747,7 +5769,7 @@ dependencies = [
"anyhow",
"async-trait",
"http 1.1.0",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"serde",
"thiserror 1.0.69",
"tower-service",
@@ -5925,16 +5947,6 @@ dependencies = [
"base64 0.13.1",
]
-[[package]]
-name = "rustls-pemfile"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
-dependencies = [
- "base64 0.22.1",
- "rustls-pki-types",
-]
-
[[package]]
name = "rustls-pki-types"
version = "1.11.0"
@@ -6499,9 +6511,9 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.5.9"
+version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
+checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -6546,7 +6558,7 @@ dependencies = [
[[package]]
name = "solana-account-decoder"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"Inflector",
"assert_matches",
@@ -6590,7 +6602,7 @@ dependencies = [
[[package]]
name = "solana-account-decoder-client-types"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"base64 0.22.1",
"bs58",
@@ -6604,9 +6616,9 @@ dependencies = [
[[package]]
name = "solana-account-info"
-version = "2.2.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0c17d606a298a205fae325489fbed88ee6dc4463c111672172327e741c8905d"
+checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da"
dependencies = [
"bincode",
"serde",
@@ -6617,7 +6629,7 @@ dependencies = [
[[package]]
name = "solana-accounts-bench"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 2.33.3",
"log",
@@ -6634,7 +6646,7 @@ dependencies = [
[[package]]
name = "solana-accounts-cluster-bench"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 2.33.3",
"log",
@@ -6679,8 +6691,9 @@ dependencies = [
[[package]]
name = "solana-accounts-db"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
+ "agave-reserved-account-keys",
"ahash 0.8.11",
"assert_matches",
"bincode",
@@ -6738,6 +6751,7 @@ dependencies = [
"solana-reward-info",
"solana-sdk-ids",
"solana-sha256-hasher",
+ "solana-signature",
"solana-signer",
"solana-slot-hashes",
"solana-slot-history",
@@ -6747,7 +6761,7 @@ dependencies = [
"solana-sysvar",
"solana-time-utils",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-vote-program",
"spl-generic-token",
@@ -6788,7 +6802,7 @@ dependencies = [
[[package]]
name = "solana-banking-bench"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-banking-stage-ingress-types",
"assert_matches",
@@ -6824,23 +6838,27 @@ dependencies = [
[[package]]
name = "solana-banks-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"borsh 1.5.7",
"futures 0.3.31",
"solana-account",
"solana-banks-interface",
"solana-banks-server",
+ "solana-clock",
"solana-commitment-config",
+ "solana-hash",
"solana-message",
- "solana-program",
+ "solana-program-pack",
"solana-pubkey",
+ "solana-rent",
"solana-runtime",
"solana-signature",
"solana-signer",
"solana-system-interface",
+ "solana-sysvar",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"tarpc",
"thiserror 2.0.12",
@@ -6850,7 +6868,7 @@ dependencies = [
[[package]]
name = "solana-banks-interface"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"serde",
"serde_derive",
@@ -6862,14 +6880,14 @@ dependencies = [
"solana-pubkey",
"solana-signature",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"tarpc",
]
[[package]]
name = "solana-banks-server"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"bincode",
@@ -6897,7 +6915,7 @@ dependencies = [
[[package]]
name = "solana-bench-streamer"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 3.2.23",
"crossbeam-channel",
@@ -6908,7 +6926,7 @@ dependencies = [
[[package]]
name = "solana-bench-tps"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"chrono",
@@ -6974,7 +6992,7 @@ dependencies = [
[[package]]
name = "solana-bench-vote"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"clap 2.33.3",
@@ -7031,7 +7049,7 @@ dependencies = [
[[package]]
name = "solana-bloom"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bv",
"fnv",
@@ -7075,7 +7093,7 @@ dependencies = [
[[package]]
name = "solana-bpf-loader-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"bincode",
@@ -7094,7 +7112,7 @@ dependencies = [
"solana-bpf-loader-program",
"solana-clock",
"solana-cpi",
- "solana-curve25519",
+ "solana-curve25519 3.0.0",
"solana-epoch-rewards",
"solana-epoch-schedule",
"solana-fee-calculator",
@@ -7125,7 +7143,7 @@ dependencies = [
"solana-sysvar",
"solana-sysvar-id",
"solana-timings",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-type-overrides",
"static_assertions",
"test-case",
@@ -7134,7 +7152,7 @@ dependencies = [
[[package]]
name = "solana-bpf-loader-program-tests"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"bincode",
@@ -7154,7 +7172,7 @@ dependencies = [
[[package]]
name = "solana-bucket-map"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bv",
"bytemuck",
@@ -7174,7 +7192,7 @@ dependencies = [
[[package]]
name = "solana-builtins"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"solana-bpf-loader-program",
@@ -7193,7 +7211,7 @@ dependencies = [
[[package]]
name = "solana-builtins-default-costs"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"ahash 0.8.11",
@@ -7213,7 +7231,7 @@ dependencies = [
[[package]]
name = "solana-cargo-build-sbf"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_cmd",
"bzip2",
@@ -7223,7 +7241,7 @@ dependencies = [
"log",
"predicates",
"regex",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"semver 1.0.26",
"serial_test",
"solana-file-download",
@@ -7234,7 +7252,7 @@ dependencies = [
[[package]]
name = "solana-cargo-test-sbf"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"cargo_metadata",
"clap 3.2.23",
@@ -7246,7 +7264,7 @@ dependencies = [
[[package]]
name = "solana-clap-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"chrono",
@@ -7276,7 +7294,7 @@ dependencies = [
[[package]]
name = "solana-clap-v3-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"chrono",
@@ -7308,7 +7326,7 @@ dependencies = [
[[package]]
name = "solana-cli"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"assert_matches",
@@ -7325,13 +7343,14 @@ dependencies = [
"log",
"num-traits",
"pretty-hex",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"semver 1.0.26",
"serde",
"serde_derive",
"serde_json",
"solana-account",
"solana-account-decoder",
+ "solana-address-lookup-table-interface",
"solana-borsh",
"solana-bpf-loader-program",
"solana-clap-utils",
@@ -7342,6 +7361,7 @@ dependencies = [
"solana-cluster-type",
"solana-commitment-config",
"solana-compute-budget-interface",
+ "solana-config-interface",
"solana-config-program-client",
"solana-connection-cache",
"solana-decode-error",
@@ -7365,7 +7385,6 @@ dependencies = [
"solana-offchain-message",
"solana-packet",
"solana-presigner",
- "solana-program",
"solana-program-runtime",
"solana-pubkey",
"solana-pubsub-client",
@@ -7404,7 +7423,7 @@ dependencies = [
[[package]]
name = "solana-cli-config"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"anyhow",
"dirs-next",
@@ -7418,7 +7437,7 @@ dependencies = [
[[package]]
name = "solana-cli-output"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"Inflector",
"agave-reserved-account-keys",
@@ -7445,16 +7464,16 @@ dependencies = [
"solana-message",
"solana-native-token",
"solana-packet",
- "solana-program",
"solana-pubkey",
"solana-rpc-client-api",
"solana-sdk-ids",
"solana-signature",
"solana-signer",
+ "solana-stake-interface",
"solana-system-interface",
"solana-sysvar",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-transaction-status",
"solana-vote-program",
@@ -7463,7 +7482,7 @@ dependencies = [
[[package]]
name = "solana-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-trait",
"bincode",
@@ -7509,7 +7528,7 @@ dependencies = [
[[package]]
name = "solana-client-test"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"futures-util",
"serde_json",
@@ -7586,8 +7605,6 @@ checksum = "7ace9fea2daa28354d107ea879cff107181d85cd4e0f78a2bedb10e1a428c97e"
dependencies = [
"serde",
"serde_derive",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
]
@@ -7603,7 +7620,7 @@ dependencies = [
[[package]]
name = "solana-compute-budget"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"qualifier_attr",
"solana-fee-structure",
@@ -7613,7 +7630,7 @@ dependencies = [
[[package]]
name = "solana-compute-budget-instruction"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"bincode",
@@ -7629,10 +7646,10 @@ dependencies = [
"solana-keypair",
"solana-message",
"solana-packet",
- "solana-program",
"solana-pubkey",
"solana-sdk-ids",
"solana-signer",
+ "solana-stake-interface",
"solana-svm-transaction",
"solana-system-interface",
"solana-transaction",
@@ -7647,22 +7664,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8432d2c4c22d0499aa06d62e4f7e333f81777b3d7c96050ae9e5cb71a8c3aee4"
dependencies = [
"borsh 1.5.7",
- "serde",
- "serde_derive",
"solana-instruction",
"solana-sdk-ids",
]
[[package]]
name = "solana-compute-budget-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"solana-program-runtime",
]
[[package]]
name = "solana-compute-budget-program-bench"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"criterion",
@@ -7675,22 +7690,40 @@ dependencies = [
"solana-svm-transaction",
]
+[[package]]
+name = "solana-config-interface"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fbdbcfedb467322ac9686ca61da0a1fdede2fd99a01fb2ed52b49452abd22e0"
+dependencies = [
+ "bincode",
+ "serde",
+ "serde_derive",
+ "solana-account",
+ "solana-instruction",
+ "solana-pubkey",
+ "solana-sdk-ids",
+ "solana-short-vec",
+ "solana-system-interface",
+]
+
[[package]]
name = "solana-config-program-client"
-version = "0.0.2"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e"
+checksum = "ef9867b9ffae6e48a97ce6349e7796fcb34084298e909a8fa1fe427f41b52fd4"
dependencies = [
"bincode",
"borsh 0.10.3",
"kaigan",
"serde",
+ "solana-config-interface",
"solana-program",
]
[[package]]
name = "solana-connection-cache"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-trait",
"bincode",
@@ -7715,7 +7748,7 @@ dependencies = [
[[package]]
name = "solana-core"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-banking-stage-ingress-types",
"agave-feature-set",
@@ -7735,6 +7768,7 @@ dependencies = [
"criterion",
"crossbeam-channel",
"dashmap",
+ "derive_more 1.0.0",
"etcd-client",
"fs_extra",
"futures 0.3.31",
@@ -7813,7 +7847,6 @@ dependencies = [
"solana-runtime",
"solana-runtime-transaction",
"solana-sanitize",
- "solana-sdk",
"solana-sdk-ids",
"solana-send-transaction-service",
"solana-sha256-hasher",
@@ -7865,7 +7898,7 @@ dependencies = [
[[package]]
name = "solana-cost-model"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-reserved-account-keys",
@@ -7925,7 +7958,21 @@ dependencies = [
[[package]]
name = "solana-curve25519"
-version = "2.3.0"
+version = "2.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "def3cfe5279edb64fc39111cff6dcf77b01fbfba2c02c13ced41e6a48baf4cbe"
+dependencies = [
+ "bytemuck",
+ "bytemuck_derive",
+ "curve25519-dalek 4.1.3",
+ "solana-define-syscall",
+ "subtle",
+ "thiserror 2.0.12",
+]
+
+[[package]]
+name = "solana-curve25519"
+version = "3.0.0"
dependencies = [
"bytemuck",
"bytemuck_derive",
@@ -7963,7 +8010,7 @@ dependencies = [
[[package]]
name = "solana-dos"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"clap 3.2.23",
@@ -8006,7 +8053,7 @@ dependencies = [
[[package]]
name = "solana-download-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
"solana-clock",
@@ -8017,9 +8064,9 @@ dependencies = [
[[package]]
name = "solana-ed25519-program"
-version = "2.2.2"
+version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d0fc717048fdbe5d2ee7d673d73e6a30a094002f4a29ca7630ac01b6bddec04"
+checksum = "a1feafa1691ea3ae588f99056f4bdd1293212c7ece28243d7da257c443e84753"
dependencies = [
"bytemuck",
"bytemuck_derive",
@@ -8032,7 +8079,7 @@ dependencies = [
[[package]]
name = "solana-ed25519-program-tests"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"ed25519-dalek",
@@ -8048,7 +8095,7 @@ dependencies = [
[[package]]
name = "solana-entry"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-reserved-account-keys",
"assert_matches",
@@ -8097,8 +8144,6 @@ checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7"
dependencies = [
"serde",
"serde_derive",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-sdk-ids",
"solana-sdk-macro",
@@ -8154,7 +8199,7 @@ dependencies = [
[[package]]
name = "solana-faucet"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"clap 2.33.3",
@@ -8224,8 +8269,6 @@ dependencies = [
"ahash 0.8.11",
"lazy_static",
"solana-epoch-schedule",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-pubkey",
"solana-sha256-hasher",
@@ -8233,7 +8276,7 @@ dependencies = [
[[package]]
name = "solana-fee"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"solana-fee-structure",
@@ -8255,9 +8298,9 @@ dependencies = [
[[package]]
name = "solana-fee-structure"
-version = "2.2.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f45f94a88efdb512805563181dfa1c85c60a21b6e6d602bf24a2ea88f9399d6e"
+checksum = "33adf673581c38e810bf618f745bf31b683a0a4a4377682e6aaac5d9a058dd4e"
dependencies = [
"serde",
"serde_derive",
@@ -8311,7 +8354,7 @@ dependencies = [
[[package]]
name = "solana-genesis"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"base64 0.22.1",
@@ -8371,8 +8414,6 @@ dependencies = [
"solana-cluster-type",
"solana-epoch-schedule",
"solana-fee-calculator",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-inflation",
"solana-keypair",
@@ -8390,7 +8431,7 @@ dependencies = [
[[package]]
name = "solana-genesis-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
"solana-accounts-db",
@@ -8402,7 +8443,7 @@ dependencies = [
[[package]]
name = "solana-geyser-plugin-manager"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-geyser-plugin-interface",
"bs58",
@@ -8431,7 +8472,7 @@ dependencies = [
[[package]]
name = "solana-gossip"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"anyhow",
@@ -8551,9 +8592,9 @@ dependencies = [
[[package]]
name = "solana-instruction"
-version = "2.2.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed"
+checksum = "47298e2ce82876b64f71e9d13a46bc4b9056194e7f9937ad3084385befa50885"
dependencies = [
"bincode",
"borsh 1.5.7",
@@ -8600,7 +8641,7 @@ dependencies = [
[[package]]
name = "solana-keygen"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bs58",
"clap 3.2.23",
@@ -8656,7 +8697,7 @@ dependencies = [
[[package]]
name = "solana-lattice-hash"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"base64 0.22.1",
"blake3",
@@ -8669,7 +8710,7 @@ dependencies = [
[[package]]
name = "solana-ledger"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-reserved-account-keys",
@@ -8755,7 +8796,7 @@ dependencies = [
"solana-time-utils",
"solana-timings",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-transaction-status",
"solana-vote",
@@ -8835,7 +8876,7 @@ dependencies = [
[[package]]
name = "solana-loader-v4-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"log",
@@ -8855,13 +8896,13 @@ dependencies = [
"solana-sbpf",
"solana-sdk-ids",
"solana-sysvar",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-type-overrides",
]
[[package]]
name = "solana-local-cluster"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"crossbeam-channel",
@@ -8927,7 +8968,7 @@ dependencies = [
[[package]]
name = "solana-log-analyzer"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"byte-unit",
"clap 3.2.23",
@@ -8940,7 +8981,7 @@ dependencies = [
[[package]]
name = "solana-log-collector"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
]
@@ -8960,15 +9001,15 @@ dependencies = [
[[package]]
name = "solana-measure"
-version = "2.3.0"
+version = "3.0.0"
[[package]]
name = "solana-memory-management"
-version = "2.3.0"
+version = "3.0.0"
[[package]]
name = "solana-merkle-tree"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"fast-math",
"hex",
@@ -8978,9 +9019,9 @@ dependencies = [
[[package]]
name = "solana-message"
-version = "2.3.0"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c6bf99c4570173710107a1f233f3bee226feea5fc817308707d4f7cb100a72d"
+checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b"
dependencies = [
"bincode",
"blake3",
@@ -8988,11 +9029,8 @@ dependencies = [
"serde",
"serde_derive",
"solana-bincode",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-instruction",
- "solana-logger",
"solana-pubkey",
"solana-sanitize",
"solana-sdk-ids",
@@ -9004,14 +9042,14 @@ dependencies = [
[[package]]
name = "solana-metrics"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"crossbeam-channel",
"env_logger",
"gethostname",
"log",
"rand 0.8.5",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"serial_test",
"solana-cluster-type",
"solana-sha256-hasher",
@@ -9036,7 +9074,7 @@ checksum = "307fb2f78060995979e9b4f68f833623565ed4e55d3725f100454ce78a99a1a3"
[[package]]
name = "solana-net-shaper"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 3.2.23",
"rand 0.8.5",
@@ -9048,7 +9086,7 @@ dependencies = [
[[package]]
name = "solana-net-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"anyhow",
"bincode",
@@ -9102,10 +9140,10 @@ dependencies = [
[[package]]
name = "solana-notifier"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"serde_json",
"solana-hash",
]
@@ -9144,7 +9182,7 @@ dependencies = [
[[package]]
name = "solana-perf"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"ahash 0.8.11",
"assert_matches",
@@ -9189,11 +9227,12 @@ dependencies = [
[[package]]
name = "solana-poh"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"bincode",
"core_affinity",
+ "criterion",
"crossbeam-channel",
"log",
"qualifier_attr",
@@ -9221,7 +9260,7 @@ dependencies = [
[[package]]
name = "solana-poh-bench"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 3.2.23",
"log",
@@ -9243,13 +9282,11 @@ checksum = "d650c3b4b9060082ac6b0efbbb66865089c58405bfb45de449f3f2b91eccee75"
dependencies = [
"serde",
"serde_derive",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
]
[[package]]
name = "solana-poseidon"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"ark-bn254",
"light-poseidon",
@@ -9259,9 +9296,9 @@ dependencies = [
[[package]]
name = "solana-precompile-error"
-version = "2.2.1"
+version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ff64daa2933c22982b323d88d0cdf693201ef56ac381ae16737fd5f579e07d6"
+checksum = "4d87b2c1f5de77dfe2b175ee8dd318d196aaca4d0f66f02842f80c852811f9f8"
dependencies = [
"num-traits",
"solana-decode-error",
@@ -9336,8 +9373,6 @@ dependencies = [
"solana-example-mocks",
"solana-feature-gate-interface",
"solana-fee-calculator",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-instruction",
"solana-instructions-sysvar",
@@ -9391,9 +9426,9 @@ dependencies = [
[[package]]
name = "solana-program-error"
-version = "2.2.1"
+version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa"
+checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775"
dependencies = [
"borsh 1.5.7",
"num-traits",
@@ -9407,11 +9442,10 @@ dependencies = [
[[package]]
name = "solana-program-memory"
-version = "2.2.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b0268f6c89825fb634a34bd0c3b8fdaeaecfc3728be1d622a8ee6dd577b60d4"
+checksum = "10a3ff409c17fba997b67e4e3eb996467221c62fb737fed995e4c3accefc2ab5"
dependencies = [
- "num-traits",
"solana-define-syscall",
]
@@ -9432,7 +9466,7 @@ dependencies = [
[[package]]
name = "solana-program-runtime"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"base64 0.22.1",
@@ -9471,7 +9505,7 @@ dependencies = [
"solana-sysvar",
"solana-sysvar-id",
"solana-timings",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-type-overrides",
"test-case",
"thiserror 2.0.12",
@@ -9479,7 +9513,7 @@ dependencies = [
[[package]]
name = "solana-program-test"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"assert_matches",
@@ -9514,6 +9548,7 @@ dependencies = [
"solana-msg",
"solana-native-token",
"solana-poh-config",
+ "solana-program",
"solana-program-entrypoint",
"solana-program-error",
"solana-program-runtime",
@@ -9521,9 +9556,7 @@ dependencies = [
"solana-rent",
"solana-runtime",
"solana-sbpf",
- "solana-sdk",
"solana-sdk-ids",
- "solana-sdk-macro",
"solana-signer",
"solana-stable-layout",
"solana-stake-interface",
@@ -9534,7 +9567,7 @@ dependencies = [
"solana-sysvar-id",
"solana-timings",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-vote-program",
"spl-generic-token",
@@ -9575,7 +9608,7 @@ dependencies = [
[[package]]
name = "solana-pubsub-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"anyhow",
"crossbeam-channel",
@@ -9602,7 +9635,7 @@ dependencies = [
[[package]]
name = "solana-quic-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-lock",
"async-trait",
@@ -9643,14 +9676,14 @@ dependencies = [
[[package]]
name = "solana-rayon-threadlimit"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"num_cpus",
]
[[package]]
name = "solana-remote-wallet"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"console",
@@ -9715,18 +9748,6 @@ dependencies = [
"solana-reward-info",
]
-[[package]]
-name = "solana-reserved-account-keys"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b293f4246626c0e0a991531f08848a713ada965612e99dc510963f04d12cae7"
-dependencies = [
- "lazy_static",
- "solana-feature-set",
- "solana-pubkey",
- "solana-sdk-ids",
-]
-
[[package]]
name = "solana-reward-info"
version = "2.2.1"
@@ -9735,13 +9756,11 @@ checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f"
dependencies = [
"serde",
"serde_derive",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
]
[[package]]
name = "solana-rpc"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-reserved-account-keys",
@@ -9809,6 +9828,7 @@ dependencies = [
"solana-rpc-client-api",
"solana-runtime",
"solana-runtime-transaction",
+ "solana-sdk-ids",
"solana-send-transaction-service",
"solana-sha256-hasher",
"solana-signature",
@@ -9825,7 +9845,7 @@ dependencies = [
"solana-time-utils",
"solana-tpu-client",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-transaction-status",
"solana-validator-exit",
@@ -9847,7 +9867,7 @@ dependencies = [
[[package]]
name = "solana-rpc-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"async-trait",
@@ -9860,7 +9880,7 @@ dependencies = [
"jsonrpc-core",
"jsonrpc-http-server",
"log",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"reqwest-middleware",
"semver 1.0.26",
"serde",
@@ -9878,7 +9898,6 @@ dependencies = [
"solana-instruction",
"solana-keypair",
"solana-message",
- "solana-program",
"solana-pubkey",
"solana-rpc-client-api",
"solana-signature",
@@ -9888,17 +9907,18 @@ dependencies = [
"solana-transaction-error",
"solana-transaction-status-client-types",
"solana-version",
+ "solana-vote-interface",
"static_assertions",
"tokio",
]
[[package]]
name = "solana-rpc-client-api"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"anyhow",
"jsonrpc-core",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"reqwest-middleware",
"serde",
"serde_derive",
@@ -9914,7 +9934,7 @@ dependencies = [
[[package]]
name = "solana-rpc-client-nonce-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"anyhow",
"clap 2.33.3",
@@ -9943,7 +9963,7 @@ dependencies = [
[[package]]
name = "solana-rpc-client-types"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"base64 0.22.1",
"bs58",
@@ -9968,14 +9988,14 @@ dependencies = [
[[package]]
name = "solana-rpc-test"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"bs58",
"crossbeam-channel",
"futures-util",
"log",
- "reqwest 0.12.15",
+ "reqwest 0.12.19",
"serde",
"serde_json",
"solana-account-decoder",
@@ -10006,7 +10026,7 @@ dependencies = [
[[package]]
name = "solana-runtime"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-precompiles",
@@ -10099,7 +10119,6 @@ dependencies = [
"solana-perf",
"solana-poh-config",
"solana-precompile-error",
- "solana-program",
"solana-program-runtime",
"solana-pubkey",
"solana-rayon-threadlimit",
@@ -10109,9 +10128,7 @@ dependencies = [
"solana-reward-info",
"solana-runtime",
"solana-runtime-transaction",
- "solana-sdk",
"solana-sdk-ids",
- "solana-sdk-macro",
"solana-secp256k1-program",
"solana-seed-derivable",
"solana-serde",
@@ -10134,7 +10151,7 @@ dependencies = [
"solana-time-utils",
"solana-timings",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-transaction-status-client-types",
"solana-unified-scheduler-logic",
@@ -10156,7 +10173,7 @@ dependencies = [
[[package]]
name = "solana-runtime-transaction"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-reserved-account-keys",
@@ -10172,7 +10189,6 @@ dependencies = [
"solana-instruction",
"solana-keypair",
"solana-message",
- "solana-program",
"solana-pubkey",
"solana-sdk-ids",
"solana-signature",
@@ -10182,6 +10198,7 @@ dependencies = [
"solana-system-transaction",
"solana-transaction",
"solana-transaction-error",
+ "solana-vote-interface",
"thiserror 2.0.12",
]
@@ -10210,77 +10227,6 @@ dependencies = [
"winapi 0.3.9",
]
-[[package]]
-name = "solana-sdk"
-version = "2.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8af90d2ce445440e0548fa4a5f96fe8b265c22041a68c942012ffadd029667d"
-dependencies = [
- "bincode",
- "bs58",
- "getrandom 0.1.16",
- "js-sys",
- "serde",
- "serde_json",
- "solana-account",
- "solana-bn254",
- "solana-client-traits",
- "solana-cluster-type",
- "solana-commitment-config",
- "solana-compute-budget-interface",
- "solana-decode-error",
- "solana-derivation-path",
- "solana-ed25519-program",
- "solana-epoch-info",
- "solana-epoch-rewards-hasher",
- "solana-feature-set",
- "solana-fee-structure",
- "solana-genesis-config",
- "solana-hard-forks",
- "solana-inflation",
- "solana-instruction",
- "solana-keypair",
- "solana-message",
- "solana-native-token",
- "solana-nonce-account",
- "solana-offchain-message",
- "solana-packet",
- "solana-poh-config",
- "solana-precompile-error",
- "solana-precompiles",
- "solana-presigner",
- "solana-program",
- "solana-program-memory",
- "solana-pubkey",
- "solana-quic-definitions",
- "solana-rent-collector",
- "solana-rent-debits",
- "solana-reserved-account-keys",
- "solana-reward-info",
- "solana-sanitize",
- "solana-sdk-ids",
- "solana-sdk-macro",
- "solana-secp256k1-program",
- "solana-secp256k1-recover",
- "solana-secp256r1-program",
- "solana-seed-derivable",
- "solana-seed-phrase",
- "solana-serde",
- "solana-serde-varint",
- "solana-short-vec",
- "solana-shred-version",
- "solana-signature",
- "solana-signer",
- "solana-system-transaction",
- "solana-time-utils",
- "solana-transaction",
- "solana-transaction-context 2.2.1",
- "solana-transaction-error",
- "solana-validator-exit",
- "thiserror 2.0.12",
- "wasm-bindgen",
-]
-
[[package]]
name = "solana-sdk-ids"
version = "2.2.1"
@@ -10333,9 +10279,9 @@ dependencies = [
[[package]]
name = "solana-secp256r1-program"
-version = "2.2.2"
+version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cda2aa1bbaceda14763c4f142a00b486f2f262cfd901bd0410649ad0404d5f7"
+checksum = "cf903cbdc36a161533812f90acfccdb434ed48982bd5dd71f3217930572c4a80"
dependencies = [
"bytemuck",
"openssl",
@@ -10373,7 +10319,7 @@ dependencies = [
[[package]]
name = "solana-send-transaction-service"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-trait",
"crossbeam-channel",
@@ -10534,7 +10480,7 @@ dependencies = [
[[package]]
name = "solana-stake-accounts"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"clap 2.33.3",
"solana-account",
@@ -10586,7 +10532,7 @@ dependencies = [
[[package]]
name = "solana-stake-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"assert_matches",
@@ -10615,7 +10561,7 @@ dependencies = [
"solana-svm-feature-set",
"solana-sysvar",
"solana-sysvar-id",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-type-overrides",
"solana-vote-interface",
"solana-vote-program",
@@ -10624,7 +10570,7 @@ dependencies = [
[[package]]
name = "solana-stake-program-tests"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"assert_matches",
@@ -10647,7 +10593,7 @@ dependencies = [
[[package]]
name = "solana-storage-bigtable"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-reserved-account-keys",
"backoff",
@@ -10680,7 +10626,7 @@ dependencies = [
"solana-system-transaction",
"solana-time-utils",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-transaction-status",
"thiserror 2.0.12",
@@ -10691,7 +10637,7 @@ dependencies = [
[[package]]
name = "solana-storage-proto"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"bs58",
@@ -10707,7 +10653,7 @@ dependencies = [
"solana-serde",
"solana-signature",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-transaction-status",
"tonic-build",
@@ -10715,7 +10661,7 @@ dependencies = [
[[package]]
name = "solana-streamer"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"async-channel",
@@ -10763,7 +10709,7 @@ dependencies = [
[[package]]
name = "solana-svm"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-reserved-account-keys",
@@ -10817,7 +10763,6 @@ dependencies = [
"solana-rent-collector",
"solana-rent-debits",
"solana-sbpf",
- "solana-sdk",
"solana-sdk-ids",
"solana-secp256k1-program",
"solana-secp256r1-program",
@@ -10837,7 +10782,7 @@ dependencies = [
"solana-sysvar-id",
"solana-timings",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"solana-type-overrides",
"spl-generic-token",
@@ -10848,7 +10793,7 @@ dependencies = [
[[package]]
name = "solana-svm-callback"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"solana-account",
"solana-precompile-error",
@@ -10857,7 +10802,7 @@ dependencies = [
[[package]]
name = "solana-svm-conformance"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"prost",
"prost-build",
@@ -10866,11 +10811,11 @@ dependencies = [
[[package]]
name = "solana-svm-feature-set"
-version = "2.3.0"
+version = "3.0.0"
[[package]]
name = "solana-svm-rent-collector"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"solana-account",
"solana-clock",
@@ -10879,13 +10824,13 @@ dependencies = [
"solana-rent",
"solana-rent-collector",
"solana-sdk-ids",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
]
[[package]]
name = "solana-svm-transaction"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"solana-hash",
"solana-message",
@@ -10917,7 +10862,7 @@ dependencies = [
[[package]]
name = "solana-system-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"assert_matches",
@@ -10945,7 +10890,7 @@ dependencies = [
"solana-svm-feature-set",
"solana-system-interface",
"solana-sysvar",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-type-overrides",
]
@@ -10983,8 +10928,6 @@ dependencies = [
"solana-epoch-rewards",
"solana-epoch-schedule",
"solana-fee-calculator",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-instruction",
"solana-instructions-sysvar",
@@ -11015,7 +10958,7 @@ dependencies = [
[[package]]
name = "solana-test-validator"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"base64 0.22.1",
@@ -11062,7 +11005,7 @@ dependencies = [
[[package]]
name = "solana-thin-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"log",
@@ -11096,7 +11039,7 @@ checksum = "6af261afb0e8c39252a04d026e3ea9c405342b08c871a2ad8aa5448e068c784c"
[[package]]
name = "solana-timings"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"eager",
"enum-iterator",
@@ -11105,7 +11048,7 @@ dependencies = [
[[package]]
name = "solana-tls-utils"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"rustls 0.23.27",
"solana-keypair",
@@ -11116,7 +11059,7 @@ dependencies = [
[[package]]
name = "solana-tokens"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"bincode",
@@ -11163,7 +11106,7 @@ dependencies = [
[[package]]
name = "solana-tps-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"log",
"solana-account",
@@ -11194,7 +11137,7 @@ dependencies = [
[[package]]
name = "solana-tpu-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-trait",
"bincode",
@@ -11226,7 +11169,7 @@ dependencies = [
[[package]]
name = "solana-tpu-client-next"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-trait",
"crossbeam-channel",
@@ -11267,12 +11210,9 @@ dependencies = [
"serde_derive",
"solana-bincode",
"solana-feature-set",
- "solana-frozen-abi",
- "solana-frozen-abi-macro",
"solana-hash",
"solana-instruction",
"solana-keypair",
- "solana-logger",
"solana-message",
"solana-precompiles",
"solana-pubkey",
@@ -11288,23 +11228,7 @@ dependencies = [
[[package]]
name = "solana-transaction-context"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5022de04cbba05377f68bf848c8c1322ead733f88a657bf792bb40f3257b8218"
-dependencies = [
- "bincode",
- "serde",
- "serde_derive",
- "solana-account",
- "solana-instruction",
- "solana-pubkey",
- "solana-rent",
- "solana-signature",
-]
-
-[[package]]
-name = "solana-transaction-context"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"serde",
@@ -11318,13 +11242,13 @@ dependencies = [
"solana-sdk-ids",
"solana-signature",
"solana-system-interface",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"static_assertions",
]
[[package]]
name = "solana-transaction-dos"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bincode",
"clap 2.33.3",
@@ -11375,7 +11299,7 @@ dependencies = [
[[package]]
name = "solana-transaction-metrics-tracker"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"base64 0.22.1",
"bincode",
@@ -11393,7 +11317,7 @@ dependencies = [
[[package]]
name = "solana-transaction-status"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"Inflector",
"agave-reserved-account-keys",
@@ -11437,7 +11361,7 @@ dependencies = [
[[package]]
name = "solana-transaction-status-client-types"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"base64 0.22.1",
"bincode",
@@ -11451,14 +11375,14 @@ dependencies = [
"solana-reward-info",
"solana-signature",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-transaction-error",
"thiserror 2.0.12",
]
[[package]]
name = "solana-turbine"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"agave-xdp",
@@ -11515,7 +11439,7 @@ dependencies = [
[[package]]
name = "solana-type-overrides"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"futures 0.3.31",
"rand 0.8.5",
@@ -11524,7 +11448,7 @@ dependencies = [
[[package]]
name = "solana-udp-client"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"async-trait",
"solana-connection-cache",
@@ -11539,7 +11463,7 @@ dependencies = [
[[package]]
name = "solana-unified-scheduler-logic"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"solana-instruction",
@@ -11553,7 +11477,7 @@ dependencies = [
[[package]]
name = "solana-unified-scheduler-pool"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-banking-stage-ingress-types",
"aquamarine",
@@ -11592,7 +11516,7 @@ dependencies = [
[[package]]
name = "solana-upload-perf"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"serde_json",
"solana-metrics",
@@ -11606,7 +11530,7 @@ checksum = "7bbf6d7a3c0b28dd5335c52c0e9eae49d0ae489a8f324917faf0ded65a812c1d"
[[package]]
name = "solana-version"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"rand 0.8.5",
@@ -11621,7 +11545,7 @@ dependencies = [
[[package]]
name = "solana-vortexor"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-banking-stage-ingress-types",
"assert_matches",
@@ -11675,7 +11599,7 @@ dependencies = [
[[package]]
name = "solana-vortexor-receiver"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"assert_matches",
"solana-perf",
@@ -11684,7 +11608,7 @@ dependencies = [
[[package]]
name = "solana-vote"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"arbitrary",
"bincode",
@@ -11745,7 +11669,7 @@ dependencies = [
[[package]]
name = "solana-vote-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"assert_matches",
@@ -11777,7 +11701,7 @@ dependencies = [
"solana-signer",
"solana-slot-hashes",
"solana-transaction",
- "solana-transaction-context 2.3.0",
+ "solana-transaction-context",
"solana-vote-interface",
"test-case",
"thiserror 2.0.12",
@@ -11785,7 +11709,7 @@ dependencies = [
[[package]]
name = "solana-wen-restart"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"anyhow",
"assert_matches",
@@ -11806,7 +11730,6 @@ dependencies = [
"solana-keypair",
"solana-ledger",
"solana-logger",
- "solana-program",
"solana-pubkey",
"solana-runtime",
"solana-shred-version",
@@ -11815,13 +11738,14 @@ dependencies = [
"solana-time-utils",
"solana-timings",
"solana-vote",
+ "solana-vote-interface",
"solana-vote-program",
"tempfile",
]
[[package]]
name = "solana-zk-elgamal-proof-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bytemuck",
"criterion",
@@ -11832,12 +11756,12 @@ dependencies = [
"solana-log-collector",
"solana-program-runtime",
"solana-sdk-ids",
- "solana-zk-sdk",
+ "solana-zk-sdk 3.0.0",
]
[[package]]
name = "solana-zk-elgamal-proof-program-tests"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bytemuck",
"solana-account",
@@ -11851,12 +11775,12 @@ dependencies = [
"solana-system-interface",
"solana-transaction",
"solana-transaction-error",
- "solana-zk-sdk",
+ "solana-zk-sdk 3.0.0",
]
[[package]]
name = "solana-zk-keygen"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"bs58",
"clap 3.2.23",
@@ -11875,7 +11799,44 @@ dependencies = [
[[package]]
name = "solana-zk-sdk"
-version = "2.3.0"
+version = "2.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15045540c315a9b8ea056323e73320e76098dfdaac9e65b1b33fe9c2f3c9b9e1"
+dependencies = [
+ "aes-gcm-siv",
+ "base64 0.22.1",
+ "bincode",
+ "bytemuck",
+ "bytemuck_derive",
+ "curve25519-dalek 4.1.3",
+ "itertools 0.12.1",
+ "js-sys",
+ "lazy_static",
+ "merlin",
+ "num-derive",
+ "num-traits",
+ "rand 0.8.5",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha3",
+ "solana-derivation-path",
+ "solana-instruction",
+ "solana-pubkey",
+ "solana-sdk-ids",
+ "solana-seed-derivable",
+ "solana-seed-phrase",
+ "solana-signature",
+ "solana-signer",
+ "subtle",
+ "thiserror 2.0.12",
+ "wasm-bindgen",
+ "zeroize",
+]
+
+[[package]]
+name = "solana-zk-sdk"
+version = "3.0.0"
dependencies = [
"aes-gcm-siv",
"base64 0.22.1",
@@ -11911,7 +11872,7 @@ dependencies = [
[[package]]
name = "solana-zk-token-proof-program"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"agave-feature-set",
"bytemuck",
@@ -11928,7 +11889,7 @@ dependencies = [
[[package]]
name = "solana-zk-token-sdk"
-version = "2.3.0"
+version = "3.0.0"
dependencies = [
"aes-gcm-siv",
"base64 0.22.1",
@@ -11945,7 +11906,7 @@ dependencies = [
"serde_derive",
"serde_json",
"sha3",
- "solana-curve25519",
+ "solana-curve25519 3.0.0",
"solana-derivation-path",
"solana-instruction",
"solana-keypair",
@@ -12056,7 +12017,7 @@ dependencies = [
"solana-sdk-ids",
"solana-system-interface",
"solana-sysvar",
- "solana-zk-sdk",
+ "solana-zk-sdk 2.2.15",
"spl-pod",
"spl-token-confidential-transfer-proof-extraction",
]
@@ -12116,7 +12077,7 @@ dependencies = [
"solana-program-error",
"solana-program-option",
"solana-pubkey",
- "solana-zk-sdk",
+ "solana-zk-sdk 2.2.15",
"thiserror 2.0.12",
]
@@ -12226,7 +12187,7 @@ dependencies = [
"solana-security-txt",
"solana-system-interface",
"solana-sysvar",
- "solana-zk-sdk",
+ "solana-zk-sdk 2.2.15",
"spl-elgamal-registry",
"spl-memo",
"spl-pod",
@@ -12249,8 +12210,8 @@ checksum = "94ab20faf7b5edaa79acd240e0f21d5a2ef936aa99ed98f698573a2825b299c4"
dependencies = [
"base64 0.22.1",
"bytemuck",
- "solana-curve25519",
- "solana-zk-sdk",
+ "solana-curve25519 2.2.15",
+ "solana-zk-sdk 2.2.15",
]
[[package]]
@@ -12261,14 +12222,14 @@ checksum = "fe2629860ff04c17bafa9ba4bed8850a404ecac81074113e1f840dbd0ebb7bd6"
dependencies = [
"bytemuck",
"solana-account-info",
- "solana-curve25519",
+ "solana-curve25519 2.2.15",
"solana-instruction",
"solana-instructions-sysvar",
"solana-msg",
"solana-program-error",
"solana-pubkey",
"solana-sdk-ids",
- "solana-zk-sdk",
+ "solana-zk-sdk 2.2.15",
"spl-pod",
"thiserror 2.0.12",
]
@@ -12280,7 +12241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae5b124840d4aed474cef101d946a798b806b46a509ee4df91021e1ab1cef3ef"
dependencies = [
"curve25519-dalek 4.1.3",
- "solana-zk-sdk",
+ "solana-zk-sdk 2.2.15",
"thiserror 2.0.12",
]
@@ -13066,7 +13027,7 @@ dependencies = [
"percent-encoding 2.3.1",
"pin-project",
"prost",
- "rustls-pemfile 1.0.0",
+ "rustls-pemfile",
"tokio",
"tokio-rustls 0.24.1",
"tokio-stream",
@@ -13125,6 +13086,24 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "tower-http"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+dependencies = [
+ "bitflags 2.9.1",
+ "bytes",
+ "futures-util",
+ "http 1.1.0",
+ "http-body 1.0.1",
+ "iri-string",
+ "pin-project-lite",
+ "tower 0.5.2",
+ "tower-layer",
+ "tower-service",
+]
+
[[package]]
name = "tower-layer"
version = "0.3.3"
@@ -13618,6 +13597,15 @@ dependencies = [
"rustls-pki-types",
]
+[[package]]
+name = "webpki-roots"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb"
+dependencies = [
+ "rustls-pki-types",
+]
+
[[package]]
name = "which"
version = "4.2.2"
@@ -13698,7 +13686,7 @@ version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
dependencies = [
- "windows-result 0.1.1",
+ "windows-result",
"windows-targets 0.52.6",
]
@@ -13708,17 +13696,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
-[[package]]
-name = "windows-registry"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
-dependencies = [
- "windows-result 0.3.1",
- "windows-strings",
- "windows-targets 0.53.0",
-]
-
[[package]]
name = "windows-result"
version = "0.1.1"
@@ -13728,24 +13705,6 @@ dependencies = [
"windows-targets 0.52.6",
]
-[[package]]
-name = "windows-result"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
-dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
-dependencies = [
- "windows-link",
-]
-
[[package]]
name = "windows-sys"
version = "0.45.0"
@@ -13821,29 +13780,13 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm 0.52.6",
+ "windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
-[[package]]
-name = "windows-targets"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
-dependencies = [
- "windows_aarch64_gnullvm 0.53.0",
- "windows_aarch64_msvc 0.53.0",
- "windows_i686_gnu 0.53.0",
- "windows_i686_gnullvm 0.53.0",
- "windows_i686_msvc 0.53.0",
- "windows_x86_64_gnu 0.53.0",
- "windows_x86_64_gnullvm 0.53.0",
- "windows_x86_64_msvc 0.53.0",
-]
-
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
@@ -13862,12 +13805,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
-
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
@@ -13886,12 +13823,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
-
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
@@ -13910,24 +13841,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-[[package]]
-name = "windows_i686_gnu"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
-
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
-
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
@@ -13946,12 +13865,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-[[package]]
-name = "windows_i686_msvc"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
-
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
@@ -13970,12 +13883,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
-
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
@@ -13994,12 +13901,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
-
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
@@ -14018,12 +13919,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
-
[[package]]
name = "winnow"
version = "0.5.16"
diff --git a/Cargo.toml b/Cargo.toml
index de92aaedc1e2e0..64595a07ca96f6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,19 +1,3 @@
-[profile.release-with-debug]
-inherits = "release"
-debug = true
-split-debuginfo = "packed"
-lto = false # Preserve the 'thin local LTO' for this build.
-
-[profile.release]
-split-debuginfo = "unpacked"
-lto = "thin"
-
-[profile.release-with-lto]
-inherits = "release"
-split-debuginfo = "unpacked"
-lto = "thin"
-codegen-units = 1
-
[workspace]
members = [
"account-decoder",
@@ -165,13 +149,16 @@ exclude = ["programs/sbf", "svm/examples", "svm/tests/example-programs"]
resolver = "2"
[workspace.package]
-version = "2.3.0"
+version = "3.0.0"
authors = ["Anza Maintainers "]
repository = "https://github.com/anza-xyz/agave"
homepage = "https://anza.xyz/"
license = "Apache-2.0"
edition = "2021"
+[workspace.lints.rust]
+warnings = "deny"
+
[workspace.lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
@@ -179,9 +166,6 @@ check-cfg = [
'cfg(feature, values("frozen-abi", "no-entrypoint"))',
]
-[workspace.lints.rust]
-warnings = "deny"
-
# Clippy lint configuration that can not be applied in clippy.toml
[workspace.lints.clippy]
arithmetic_side_effects = "deny"
@@ -191,18 +175,19 @@ used_underscore_binding = "deny"
[workspace.dependencies]
Inflector = "0.11.4"
-axum = "0.7.9"
-aya = "0.13"
-agave-banking-stage-ingress-types = { path = "banking-stage-ingress-types", version = "=2.3.0" }
-agave-feature-set = { path = "feature-set", version = "=2.3.0" }
-agave-precompiles = { path = "precompiles", version = "=2.3.0" }
-agave-reserved-account-keys = { path = "reserved-account-keys", version = "=2.3.0" }
-agave-transaction-view = { path = "transaction-view", version = "=2.3.0" }
-agave-xdp = { path = "xdp", version = "=2.3.0" }
-aquamarine = "0.6.0"
aes-gcm-siv = "0.11.1"
+agave-banking-stage-ingress-types = { path = "banking-stage-ingress-types", version = "=3.0.0" }
+agave-cargo-registry = { path = "cargo-registry", version = "=3.0.0" }
+agave-feature-set = { path = "feature-set", version = "=3.0.0" }
+agave-geyser-plugin-interface = { path = "geyser-plugin-interface", version = "=3.0.0" }
+agave-precompiles = { path = "precompiles", version = "=3.0.0" }
+agave-reserved-account-keys = { path = "reserved-account-keys", version = "=3.0.0" }
+agave-thread-manager = { path = "thread-manager", version = "=3.0.0" }
+agave-transaction-view = { path = "transaction-view", version = "=3.0.0" }
+agave-xdp = { path = "xdp", version = "=3.0.0" }
ahash = "0.8.11"
anyhow = "1.0.98"
+aquamarine = "0.6.0"
arbitrary = "1.4.1"
ark-bn254 = "0.4.0"
ark-ec = "0.4.0"
@@ -217,6 +202,8 @@ async-channel = "1.9.0"
async-lock = "3.4.0"
async-trait = "0.1.88"
atty = "0.2.11"
+axum = "0.7.9"
+aya = "0.13"
backoff = "0.4.0"
base64 = "0.22.1"
bincode = "1.3.3"
@@ -233,18 +220,18 @@ bytes = "1.10"
bzip2 = "0.4.4"
caps = "0.5.5"
cargo_metadata = "0.15.4"
-cfg_eval = "0.1.2"
cfg-if = "1.0.0"
+cfg_eval = "0.1.2"
chrono = { version = "0.4.41", default-features = false }
chrono-humanize = "0.2.3"
clap = "2.33.1"
+# Remove this dependency when procedural macros will support non-inline modules.
+conditional-mod = "0.1.0"
console = "0.15.11"
console_error_panic_hook = "0.1.7"
console_log = "0.2.2"
const_format = "0.2.34"
core_affinity = "0.5.10"
-# Remove this dependency when procedural macros will support non-inline modules.
-conditional-mod = "0.1.0"
criterion = "0.5.1"
criterion-stats = "0.3.0"
crossbeam-channel = "0.5.15"
@@ -269,8 +256,8 @@ env_logger = "0.9.3"
etcd-client = "0.11.1"
fast-math = "0.1"
fd-lock = "3.0.13"
-flate2 = "1.0.31"
five8_const = "0.1.4"
+flate2 = "1.0.31"
fnv = "1.0.7"
fs_extra = "1.3.0"
futures = "0.3.31"
@@ -324,7 +311,7 @@ nix = "0.30.1"
num-bigint = "0.4.6"
num-derive = "0.4"
num-traits = "0.2"
-num_cpus = "1.16.0"
+num_cpus = "1.17.0"
num_enum = "0.7.3"
openssl = "0.10"
parking_lot = "0.12"
@@ -353,7 +340,7 @@ rand_chacha0-2 = { package = "rand_chacha", version = "0.2.2" }
rayon = "1.10.0"
reed-solomon-erasure = "6.0.0"
regex = "1.11.1"
-reqwest = { version = "0.12.15", default-features = false }
+reqwest = { version = "0.12.19", default-features = false }
reqwest-middleware = "0.4.2"
rolling-file = "0.2.0"
rpassword = "7.4"
@@ -377,209 +364,203 @@ siphasher = "1.0.1"
slab = "0.4.9"
smallvec = "1.15.0"
smpl_jwt = "0.7.1"
-socket2 = "0.5.9"
+socket2 = "0.5.10"
soketto = "0.7"
solana-account = "2.2.1"
-solana-account-decoder = { path = "account-decoder", version = "=2.3.0" }
-solana-account-decoder-client-types = { path = "account-decoder-client-types", version = "=2.3.0" }
-solana-account-info = "2.2.1"
-solana-accounts-db = { path = "accounts-db", version = "=2.3.0" }
+solana-account-decoder = { path = "account-decoder", version = "=3.0.0" }
+solana-account-decoder-client-types = { path = "account-decoder-client-types", version = "=3.0.0" }
+solana-account-info = "2.3.0"
+solana-accounts-db = { path = "accounts-db", version = "=3.0.0" }
solana-address-lookup-table-interface = "2.2.2"
solana-atomic-u64 = "2.2.1"
-solana-banks-client = { path = "banks-client", version = "=2.3.0" }
-solana-banks-interface = { path = "banks-interface", version = "=2.3.0" }
-solana-banks-server = { path = "banks-server", version = "=2.3.0" }
-solana-bench-tps = { path = "bench-tps", version = "=2.3.0" }
+solana-banks-client = { path = "banks-client", version = "=3.0.0" }
+solana-banks-interface = { path = "banks-interface", version = "=3.0.0" }
+solana-banks-server = { path = "banks-server", version = "=3.0.0" }
+solana-bench-tps = { path = "bench-tps", version = "=3.0.0" }
solana-big-mod-exp = "2.2.1"
solana-bincode = "2.2.1"
solana-blake3-hasher = "2.2.1"
-solana-bloom = { path = "bloom", version = "=2.3.0" }
+solana-bloom = { path = "bloom", version = "=3.0.0" }
solana-bn254 = "2.2.2"
solana-borsh = "2.2.1"
-solana-bpf-loader-program = { path = "programs/bpf_loader", version = "=2.3.0" }
-solana-bucket-map = { path = "bucket_map", version = "=2.3.0" }
-solana-builtins = { path = "builtins", version = "=2.3.0" }
-solana-builtins-default-costs = { path = "builtins-default-costs", version = "=2.3.0" }
-agave-cargo-registry = { path = "cargo-registry", version = "=2.3.0" }
-agave-thread-manager = { path = "thread-manager", version = "=2.3.0" }
-solana-clap-utils = { path = "clap-utils", version = "=2.3.0" }
-solana-clap-v3-utils = { path = "clap-v3-utils", version = "=2.3.0" }
-solana-cli = { path = "cli", version = "=2.3.0" }
-solana-cli-config = { path = "cli-config", version = "=2.3.0" }
-solana-cli-output = { path = "cli-output", version = "=2.3.0" }
-solana-client = { path = "client", version = "=2.3.0" }
+solana-bpf-loader-program = { path = "programs/bpf_loader", version = "=3.0.0" }
+solana-bucket-map = { path = "bucket_map", version = "=3.0.0" }
+solana-builtins = { path = "builtins", version = "=3.0.0" }
+solana-builtins-default-costs = { path = "builtins-default-costs", version = "=3.0.0" }
+solana-clap-utils = { path = "clap-utils", version = "=3.0.0" }
+solana-clap-v3-utils = { path = "clap-v3-utils", version = "=3.0.0" }
+solana-cli = { path = "cli", version = "=3.0.0" }
+solana-cli-config = { path = "cli-config", version = "=3.0.0" }
+solana-cli-output = { path = "cli-output", version = "=3.0.0" }
+solana-client = { path = "client", version = "=3.0.0" }
solana-client-traits = "2.2.1"
solana-clock = "2.2.2"
solana-cluster-type = "2.2.1"
solana-commitment-config = "2.2.1"
-solana-compute-budget = { path = "compute-budget", version = "=2.3.0" }
-solana-compute-budget-instruction = { path = "compute-budget-instruction", version = "=2.3.0" }
+solana-compute-budget = { path = "compute-budget", version = "=3.0.0" }
+solana-compute-budget-instruction = { path = "compute-budget-instruction", version = "=3.0.0" }
solana-compute-budget-interface = "2.2.2"
-solana-compute-budget-program = { path = "programs/compute-budget", version = "=2.3.0" }
-solana-config-program-client = "0.0.2"
-solana-connection-cache = { path = "connection-cache", version = "=2.3.0", default-features = false }
-solana-core = { path = "core", version = "=2.3.0" }
-solana-cost-model = { path = "cost-model", version = "=2.3.0" }
+solana-compute-budget-program = { path = "programs/compute-budget", version = "=3.0.0" }
+solana-config-interface = "1.0.0"
+solana-config-program-client = "1.1.0"
+solana-connection-cache = { path = "connection-cache", version = "=3.0.0", default-features = false }
+solana-core = { path = "core", version = "=3.0.0" }
+solana-cost-model = { path = "cost-model", version = "=3.0.0" }
solana-cpi = "2.2.1"
-solana-curve25519 = { path = "curves/curve25519", version = "=2.3.0" }
+solana-curve25519 = { path = "curves/curve25519", version = "=3.0.0" }
solana-decode-error = "2.2.1"
solana-define-syscall = "2.3.0"
solana-derivation-path = "2.2.1"
-solana-download-utils = { path = "download-utils", version = "=2.3.0" }
-solana-ed25519-program = "2.2.2"
-solana-entry = { path = "entry", version = "=2.3.0" }
-solana-program-entrypoint = "2.2.1"
+solana-download-utils = { path = "download-utils", version = "=3.0.0" }
+solana-ed25519-program = "2.2.3"
+solana-entry = { path = "entry", version = "=3.0.0" }
solana-epoch-info = "2.2.1"
solana-epoch-rewards = "2.2.1"
solana-epoch-rewards-hasher = "2.2.1"
solana-epoch-schedule = "2.2.1"
solana-example-mocks = "2.2.1"
-solana-faucet = { path = "faucet", version = "=2.3.0" }
+solana-faucet = { path = "faucet", version = "=3.0.0" }
solana-feature-gate-client = "0.0.2"
solana-feature-gate-interface = "2.2.2"
+solana-fee = { path = "fee", version = "=3.0.0" }
solana-fee-calculator = "2.2.1"
-solana-fee = { path = "fee", version = "=2.3.0" }
-solana-fee-structure = "2.2.1"
+solana-fee-structure = "2.3.0"
+solana-file-download = "2.2.1"
solana-frozen-abi = "2.2.2"
solana-frozen-abi-macro = "2.2.1"
-solana-tps-client = { path = "tps-client", version = "=2.3.0" }
-solana-file-download = "2.2.1"
-solana-genesis = { path = "genesis", version = "=2.3.0" }
+solana-genesis = { path = "genesis", version = "=3.0.0" }
solana-genesis-config = "2.2.1"
-solana-genesis-utils = { path = "genesis-utils", version = "=2.3.0" }
-agave-geyser-plugin-interface = { path = "geyser-plugin-interface", version = "=2.3.0" }
-solana-geyser-plugin-manager = { path = "geyser-plugin-manager", version = "=2.3.0" }
-solana-gossip = { path = "gossip", version = "=2.3.0" }
+solana-genesis-utils = { path = "genesis-utils", version = "=3.0.0" }
+solana-geyser-plugin-manager = { path = "geyser-plugin-manager", version = "=3.0.0" }
+solana-gossip = { path = "gossip", version = "=3.0.0" }
solana-hard-forks = "2.2.1"
solana-hash = "2.3.0"
solana-inflation = "2.2.1"
-solana-instruction = "2.2.1"
+solana-instruction = "2.3.0"
solana-instructions-sysvar = "2.2.2"
solana-keccak-hasher = "2.2.1"
solana-keypair = "2.2.1"
solana-last-restart-slot = "2.2.1"
-solana-lattice-hash = { path = "lattice-hash", version = "=2.3.0" }
-solana-ledger = { path = "ledger", version = "=2.3.0" }
+solana-lattice-hash = { path = "lattice-hash", version = "=3.0.0" }
+solana-ledger = { path = "ledger", version = "=3.0.0" }
solana-loader-v2-interface = "2.2.1"
solana-loader-v3-interface = "5.0.0"
solana-loader-v4-interface = "2.2.1"
-solana-loader-v4-program = { path = "programs/loader-v4", version = "=2.3.0" }
-solana-local-cluster = { path = "local-cluster", version = "=2.3.0" }
-solana-log-collector = { path = "log-collector", version = "=2.3.0" }
+solana-loader-v4-program = { path = "programs/loader-v4", version = "=3.0.0" }
+solana-local-cluster = { path = "local-cluster", version = "=3.0.0" }
+solana-log-collector = { path = "log-collector", version = "=3.0.0" }
solana-logger = "2.3.1"
-solana-measure = { path = "measure", version = "=2.3.0" }
-solana-merkle-tree = { path = "merkle-tree", version = "=2.3.0" }
-solana-message = "2.3.0"
-solana-metrics = { path = "metrics", version = "=2.3.0" }
+solana-measure = { path = "measure", version = "=3.0.0" }
+solana-merkle-tree = { path = "merkle-tree", version = "=3.0.0" }
+solana-message = "2.4.0"
+solana-metrics = { path = "metrics", version = "=3.0.0" }
solana-msg = "2.2.1"
solana-native-token = "2.2.2"
-solana-net-utils = { path = "net-utils", version = "=2.3.0" }
+solana-net-utils = { path = "net-utils", version = "=3.0.0" }
solana-nohash-hasher = "0.2.1"
solana-nonce = "2.2.1"
solana-nonce-account = "2.2.1"
-solana-notifier = { path = "notifier", version = "=2.3.0" }
+solana-notifier = { path = "notifier", version = "=3.0.0" }
solana-offchain-message = "2.2.1"
-solana-package-metadata = "2.2.1"
-solana-package-metadata-macro = "2.2.1"
solana-packet = "2.2.1"
-solana-perf = { path = "perf", version = "=2.3.0" }
-solana-poh = { path = "poh", version = "=2.3.0" }
+solana-perf = { path = "perf", version = "=3.0.0" }
+solana-poh = { path = "poh", version = "=3.0.0" }
solana-poh-config = "2.2.1"
-solana-poseidon = { path = "poseidon", version = "=2.3.0" }
-solana-precompile-error = "2.2.1"
+solana-poseidon = { path = "poseidon", version = "=3.0.0" }
+solana-precompile-error = "2.2.2"
solana-presigner = "2.2.1"
solana-program = { version = "2.2.1", default-features = false }
-solana-program-error = "2.2.1"
-solana-program-memory = "2.2.1"
+solana-program-entrypoint = "2.2.1"
+solana-program-error = "2.2.2"
+solana-program-memory = "2.3.0"
solana-program-option = "2.2.1"
solana-program-pack = "2.2.1"
-solana-program-runtime = { path = "program-runtime", version = "=2.3.0" }
-solana-program-test = { path = "program-test", version = "=2.3.0" }
+solana-program-runtime = { path = "program-runtime", version = "=3.0.0" }
+solana-program-test = { path = "program-test", version = "=3.0.0" }
solana-pubkey = { version = "2.4.0", default-features = false }
-solana-pubsub-client = { path = "pubsub-client", version = "=2.3.0" }
-solana-quic-client = { path = "quic-client", version = "=2.3.0" }
+solana-pubsub-client = { path = "pubsub-client", version = "=3.0.0" }
+solana-quic-client = { path = "quic-client", version = "=3.0.0" }
solana-quic-definitions = "2.2.1"
-solana-rayon-threadlimit = { path = "rayon-threadlimit", version = "=2.3.0" }
-solana-remote-wallet = { path = "remote-wallet", version = "=2.3.0", default-features = false }
+solana-rayon-threadlimit = { path = "rayon-threadlimit", version = "=3.0.0" }
+solana-remote-wallet = { path = "remote-wallet", version = "=3.0.0", default-features = false }
solana-rent = "2.2.1"
solana-rent-collector = "2.2.1"
solana-rent-debits = "2.2.1"
solana-reward-info = "2.2.1"
+solana-rpc = { path = "rpc", version = "=3.0.0" }
+solana-rpc-client = { path = "rpc-client", version = "=3.0.0", default-features = false }
+solana-rpc-client-api = { path = "rpc-client-api", version = "=3.0.0" }
+solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=3.0.0" }
+solana-rpc-client-types = { path = "rpc-client-types", version = "=3.0.0" }
+solana-runtime = { path = "runtime", version = "=3.0.0" }
+solana-runtime-transaction = { path = "runtime-transaction", version = "=3.0.0" }
solana-sanitize = "2.2.1"
-solana-secp256r1-program = "2.2.2"
+solana-sbpf = "=0.11.1"
+solana-sdk-ids = "2.2.1"
+solana-secp256k1-program = "2.2.1"
+solana-secp256k1-recover = "2.2.1"
+solana-secp256r1-program = "2.2.3"
solana-seed-derivable = "2.2.1"
solana-seed-phrase = "2.2.1"
+solana-send-transaction-service = { path = "send-transaction-service", version = "=3.0.0" }
solana-serde = "2.2.1"
solana-serde-varint = "2.2.2"
solana-serialize-utils = "2.2.1"
solana-sha256-hasher = "2.2.1"
+solana-short-vec = "2.2.1"
+solana-shred-version = "2.2.1"
solana-signature = { version = "2.3.0", default-features = false }
solana-signer = "2.2.1"
solana-slot-hashes = "2.2.1"
solana-slot-history = "2.2.1"
-solana-time-utils = "2.2.1"
-solana-timings = { path = "timings", version = "=2.3.0" }
-solana-tls-utils = { path = "tls-utils", version = "=2.3.0" }
-solana-unified-scheduler-logic = { path = "unified-scheduler-logic", version = "=2.3.0" }
-solana-unified-scheduler-pool = { path = "unified-scheduler-pool", version = "=2.3.0" }
-solana-rpc = { path = "rpc", version = "=2.3.0" }
-solana-rpc-client = { path = "rpc-client", version = "=2.3.0", default-features = false }
-solana-rpc-client-api = { path = "rpc-client-api", version = "=2.3.0" }
-solana-rpc-client-types = { path = "rpc-client-types", version = "=2.3.0" }
-solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=2.3.0" }
-solana-runtime = { path = "runtime", version = "=2.3.0" }
-solana-runtime-transaction = { path = "runtime-transaction", version = "=2.3.0" }
-solana-sbpf = "=0.11.1"
-solana-sdk = { version = "2.2.2", default-features = false }
-solana-sdk-ids = "2.2.1"
-solana-sdk-macro = "2.2.1"
-solana-secp256k1-program = "2.2.1"
-solana-secp256k1-recover = "2.2.1"
-solana-send-transaction-service = { path = "send-transaction-service", version = "=2.3.0" }
-solana-short-vec = "2.2.1"
-solana-shred-version = "2.2.1"
solana-stable-layout = "2.2.1"
solana-stake-interface = { version = "1.2.1" }
-solana-stake-program = { path = "programs/stake", version = "=2.3.0" }
-solana-storage-bigtable = { path = "storage-bigtable", version = "=2.3.0" }
-solana-storage-proto = { path = "storage-proto", version = "=2.3.0" }
-solana-streamer = { path = "streamer", version = "=2.3.0" }
-solana-svm = { path = "svm", version = "=2.3.0" }
-solana-svm-callback = { path = "svm-callback", version = "=2.3.0" }
-solana-svm-conformance = { path = "svm-conformance", version = "=2.3.0" }
-solana-svm-feature-set = { path = "svm-feature-set", version = "=2.3.0" }
-solana-svm-rent-collector = { path = "svm-rent-collector", version = "=2.3.0" }
-solana-svm-transaction = { path = "svm-transaction", version = "=2.3.0" }
+solana-stake-program = { path = "programs/stake", version = "=3.0.0" }
+solana-storage-bigtable = { path = "storage-bigtable", version = "=3.0.0" }
+solana-storage-proto = { path = "storage-proto", version = "=3.0.0" }
+solana-streamer = { path = "streamer", version = "=3.0.0" }
+solana-svm = { path = "svm", version = "=3.0.0" }
+solana-svm-callback = { path = "svm-callback", version = "=3.0.0" }
+solana-svm-conformance = { path = "svm-conformance", version = "=3.0.0" }
+solana-svm-feature-set = { path = "svm-feature-set", version = "=3.0.0" }
+solana-svm-rent-collector = { path = "svm-rent-collector", version = "=3.0.0" }
+solana-svm-transaction = { path = "svm-transaction", version = "=3.0.0" }
solana-system-interface = "1.0"
-solana-system-program = { path = "programs/system", version = "=2.3.0" }
+solana-system-program = { path = "programs/system", version = "=3.0.0" }
solana-system-transaction = "2.2.1"
solana-sysvar = "2.2.2"
solana-sysvar-id = "2.2.1"
-solana-test-validator = { path = "test-validator", version = "=2.3.0" }
-solana-thin-client = { path = "thin-client", version = "=2.3.0" }
+solana-test-validator = { path = "test-validator", version = "=3.0.0" }
+solana-thin-client = { path = "thin-client", version = "=3.0.0" }
+solana-time-utils = "2.2.1"
+solana-timings = { path = "timings", version = "=3.0.0" }
+solana-tls-utils = { path = "tls-utils", version = "=3.0.0" }
+solana-tps-client = { path = "tps-client", version = "=3.0.0" }
+solana-tpu-client = { path = "tpu-client", version = "=3.0.0", default-features = false }
+solana-tpu-client-next = { path = "tpu-client-next", version = "=3.0.0" }
solana-transaction = "2.2.2"
+solana-transaction-context = { path = "transaction-context", version = "=3.0.0", features = ["bincode", "debug-signature"] }
solana-transaction-error = "2.2.1"
-solana-tpu-client = { path = "tpu-client", version = "=2.3.0", default-features = false }
-solana-tpu-client-next = { path = "tpu-client-next", version = "=2.3.0" }
-solana-transaction-context = { path = "transaction-context", version = "=2.3.0", features = ["bincode", "debug-signature"] }
-solana-transaction-status = { path = "transaction-status", version = "=2.3.0" }
-solana-transaction-status-client-types = { path = "transaction-status-client-types", version = "=2.3.0" }
-solana-transaction-metrics-tracker = { path = "transaction-metrics-tracker", version = "=2.3.0" }
-solana-turbine = { path = "turbine", version = "=2.3.0" }
-solana-type-overrides = { path = "type-overrides", version = "=2.3.0" }
-solana-udp-client = { path = "udp-client", version = "=2.3.0" }
+solana-transaction-metrics-tracker = { path = "transaction-metrics-tracker", version = "=3.0.0" }
+solana-transaction-status = { path = "transaction-status", version = "=3.0.0" }
+solana-transaction-status-client-types = { path = "transaction-status-client-types", version = "=3.0.0" }
+solana-turbine = { path = "turbine", version = "=3.0.0" }
+solana-type-overrides = { path = "type-overrides", version = "=3.0.0" }
+solana-udp-client = { path = "udp-client", version = "=3.0.0" }
+solana-unified-scheduler-logic = { path = "unified-scheduler-logic", version = "=3.0.0" }
+solana-unified-scheduler-pool = { path = "unified-scheduler-pool", version = "=3.0.0" }
solana-validator-exit = "2.2.1"
-solana-version = { path = "version", version = "=2.3.0" }
-solana-vortexor-receiver = { path = "vortexor-receiver", version = "=2.3.0" }
-solana-vote = { path = "vote", version = "=2.3.0" }
+solana-version = { path = "version", version = "=3.0.0" }
+solana-vortexor-receiver = { path = "vortexor-receiver", version = "=3.0.0" }
+solana-vote = { path = "vote", version = "=3.0.0" }
solana-vote-interface = "2.2.5"
-solana-vote-program = { path = "programs/vote", version = "=2.3.0", default-features = false }
-solana-wen-restart = { path = "wen-restart", version = "=2.3.0" }
-solana-zk-elgamal-proof-program = { path = "programs/zk-elgamal-proof", version = "=2.3.0" }
-solana-zk-keygen = { path = "zk-keygen", version = "=2.3.0" }
-solana-zk-sdk = { path = "zk-sdk", version = "=2.3.0" }
-solana-zk-token-proof-program = { path = "programs/zk-token-proof", version = "=2.3.0" }
-solana-zk-token-sdk = { path = "zk-token-sdk", version = "=2.3.0" }
+solana-vote-program = { path = "programs/vote", version = "=3.0.0", default-features = false }
+solana-wen-restart = { path = "wen-restart", version = "=3.0.0" }
+solana-zk-elgamal-proof-program = { path = "programs/zk-elgamal-proof", version = "=3.0.0" }
+solana-zk-keygen = { path = "zk-keygen", version = "=3.0.0" }
+solana-zk-sdk = { path = "zk-sdk", version = "=3.0.0" }
+solana-zk-token-proof-program = { path = "programs/zk-token-proof", version = "=3.0.0" }
+solana-zk-token-sdk = { path = "zk-token-sdk", version = "=3.0.0" }
spl-associated-token-account = "7.0.0"
spl-generic-token = "1.0.1"
spl-instruction-padding = "0.3.0"
@@ -632,6 +613,22 @@ x509-parser = "0.14.0"
zeroize = { version = "1.7", default-features = false }
zstd = "0.13.3"
+[profile.release-with-debug]
+inherits = "release"
+debug = true
+strip = false
+split-debuginfo = "off"
+
+[profile.release]
+split-debuginfo = "unpacked"
+lto = "thin"
+
+[profile.release-with-lto]
+inherits = "release"
+split-debuginfo = "unpacked"
+lto = "thin"
+codegen-units = 1
+
# curve25519-dalek uses the simd backend by default in v4 if possible,
# which has very slow performance on some platforms with opt-level 0,
# which is the default for dev and test builds.
diff --git a/account-decoder-client-types/Cargo.toml b/account-decoder-client-types/Cargo.toml
index 93b8b922b6cd6d..433ecc37929e7c 100644
--- a/account-decoder-client-types/Cargo.toml
+++ b/account-decoder-client-types/Cargo.toml
@@ -9,6 +9,14 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+all-features = true
+rustdoc-args = ["--cfg=docsrs"]
+
+[features]
+zstd = ["dep:zstd"]
+
[dependencies]
base64 = { workspace = true }
bs58 = { workspace = true, features = ["std"] }
@@ -18,11 +26,3 @@ serde_json = { workspace = true }
solana-account = { workspace = true }
solana-pubkey = { workspace = true }
zstd = { workspace = true, optional = true }
-
-[features]
-zstd = ["dep:zstd"]
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-all-features = true
-rustdoc-args = ["--cfg=docsrs"]
diff --git a/account-decoder/Cargo.toml b/account-decoder/Cargo.toml
index 1fa09e52d80eee..eb8f97da89a49c 100644
--- a/account-decoder/Cargo.toml
+++ b/account-decoder/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
Inflector = { workspace = true }
base64 = { workspace = true }
@@ -56,8 +59,5 @@ solana-hash = { workspace = true }
solana-pubkey = { workspace = true, features = ["rand"] }
spl-pod = { workspace = true }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
[lints]
workspace = true
diff --git a/account-decoder/src/validator_info.rs b/account-decoder/src/validator_info.rs
index 9d35b6d75cfa89..e0552d0c76c742 100644
--- a/account-decoder/src/validator_info.rs
+++ b/account-decoder/src/validator_info.rs
@@ -1,7 +1,6 @@
-use solana_config_program_client::instructions_bincode::ConfigState;
-
pub const MAX_SHORT_FIELD_LENGTH: usize = 80;
pub const MAX_LONG_FIELD_LENGTH: usize = 300;
+/// Maximum size of validator configuration data (`ValidatorInfo`).
pub const MAX_VALIDATOR_INFO: u64 = 576;
solana_pubkey::declare_id!("Va1idator1nfo111111111111111111111111111111");
@@ -10,9 +9,3 @@ solana_pubkey::declare_id!("Va1idator1nfo111111111111111111111111111111");
pub struct ValidatorInfo {
pub info: String,
}
-
-impl ConfigState for ValidatorInfo {
- fn max_space() -> u64 {
- MAX_VALIDATOR_INFO
- }
-}
diff --git a/accounts-bench/Cargo.toml b/accounts-bench/Cargo.toml
index 7b893ecce1647a..1cfe16a4052ba5 100644
--- a/accounts-bench/Cargo.toml
+++ b/accounts-bench/Cargo.toml
@@ -8,6 +8,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
clap = { workspace = true }
log = { workspace = true }
@@ -20,9 +26,3 @@ solana-measure = { workspace = true }
solana-pubkey = { workspace = true }
solana-rent-collector = { workspace = true }
solana-version = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = []
diff --git a/accounts-cluster-bench/Cargo.toml b/accounts-cluster-bench/Cargo.toml
index 90058f4b885444..e0906f3c783d35 100644
--- a/accounts-cluster-bench/Cargo.toml
+++ b/accounts-cluster-bench/Cargo.toml
@@ -8,6 +8,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
clap = { workspace = true }
log = { workspace = true }
@@ -50,6 +53,3 @@ solana-native-token = { workspace = true }
solana-poh-config = { workspace = true }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
solana-test-validator = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/accounts-db/Cargo.toml b/accounts-db/Cargo.toml
index bb16ec4664c436..012b56e7e45c73 100644
--- a/accounts-db/Cargo.toml
+++ b/accounts-db/Cargo.toml
@@ -9,6 +9,32 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_accounts_db"
+
+[features]
+dev-context-only-utils = [
+ "dep:qualifier_attr",
+ "dep:solana-keypair",
+ "dep:solana-rent",
+ "dep:solana-signer",
+ "dep:solana-stake-program",
+ "dep:solana-vote-program",
+ "solana-account/dev-context-only-utils",
+ "solana-pubkey/rand",
+ "solana-transaction/dev-context-only-utils",
+]
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-fee-calculator/frozen-abi",
+ "solana-vote-program/frozen-abi",
+]
+
[dependencies]
ahash = { workspace = true }
bincode = { workspace = true }
@@ -80,11 +106,8 @@ tar = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
-[lib]
-crate-type = ["lib"]
-name = "solana_accounts_db"
-
[dev-dependencies]
+agave-reserved-account-keys = { workspace = true }
assert_matches = { workspace = true }
criterion = { workspace = true }
libsecp256k1 = { workspace = true }
@@ -97,34 +120,13 @@ solana-compute-budget = { workspace = true }
solana-instruction = { workspace = true }
solana-logger = { workspace = true }
solana-sdk-ids = { workspace = true }
+solana-signature = { workspace = true, features = ["rand"] }
solana-slot-history = { workspace = true }
static_assertions = { workspace = true }
strum = { workspace = true, features = ["derive"] }
strum_macros = { workspace = true }
test-case = { workspace = true }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = [
- "dep:qualifier_attr",
- "dep:solana-keypair",
- "dep:solana-rent",
- "dep:solana-signer",
- "dep:solana-stake-program",
- "dep:solana-vote-program",
- "solana-account/dev-context-only-utils",
- "solana-pubkey/rand",
- "solana-transaction/dev-context-only-utils",
-]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-fee-calculator/frozen-abi",
- "solana-vote-program/frozen-abi",
-]
-
[[bench]]
name = "bench_accounts_file"
harness = false
diff --git a/accounts-db/accounts-hash-cache-tool/Cargo.toml b/accounts-db/accounts-hash-cache-tool/Cargo.toml
index 525641902038b1..8413e5c5da492a 100644
--- a/accounts-db/accounts-hash-cache-tool/Cargo.toml
+++ b/accounts-db/accounts-hash-cache-tool/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[features]
+dev-context-only-utils = []
+
[dependencies]
ahash = { workspace = true }
anyhow = { workspace = true }
@@ -20,6 +23,3 @@ solana-accounts-db = { workspace = true }
solana-clap-utils = { workspace = true }
solana-pubkey = { workspace = true }
solana-version = { workspace = true }
-
-[features]
-dev-context-only-utils = []
diff --git a/accounts-db/benches/bench_lock_accounts.rs b/accounts-db/benches/bench_lock_accounts.rs
index 00d4805f54de13..c6ecea9fd26f60 100644
--- a/accounts-db/benches/bench_lock_accounts.rs
+++ b/accounts-db/benches/bench_lock_accounts.rs
@@ -62,16 +62,21 @@ fn create_test_transactions(lock_count: usize, read_conflicts: bool) -> Vec = transactions.chunks(batch_size).collect();
+ let batch_results = vec![Ok(()); batch_size].into_iter();
group.bench_function(name.as_str(), move |b| {
b.iter(|| {
for batch in &transaction_batches {
- let results =
- accounts.lock_accounts(black_box(batch.iter()), MAX_TX_ACCOUNT_LOCKS);
+ let results = accounts.lock_accounts(
+ black_box(batch.iter()),
+ batch_results.clone(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
accounts.unlock_accounts(batch.iter().zip(&results));
}
})
diff --git a/accounts-db/src/account_locks.rs b/accounts-db/src/account_locks.rs
index 43796937b8cc42..113b41231dd737 100644
--- a/accounts-db/src/account_locks.rs
+++ b/accounts-db/src/account_locks.rs
@@ -5,13 +5,13 @@ use {
solana_message::AccountKeys,
solana_pubkey::Pubkey,
solana_transaction::sanitized::MAX_TX_ACCOUNT_LOCKS,
- solana_transaction_error::TransactionError,
+ solana_transaction_error::{TransactionError, TransactionResult},
std::{cell::RefCell, collections::hash_map},
};
#[derive(Debug, Default)]
pub struct AccountLocks {
- write_locks: AHashSet,
+ write_locks: AHashMap,
readonly_locks: AHashMap,
}
@@ -20,29 +20,40 @@ impl AccountLocks {
/// The bool in the tuple indicates if the account is writable.
/// Returns an error if any of the accounts are already locked in a way
/// that conflicts with the requested lock.
+ /// NOTE this is the pre-SIMD83 logic and can be removed once SIMD83 is active.
pub fn try_lock_accounts<'a>(
&mut self,
keys: impl Iterator- + Clone,
- ) -> Result<(), TransactionError> {
- for (key, writable) in keys.clone() {
- if writable {
- if !self.can_write_lock(key) {
- return Err(TransactionError::AccountInUse);
- }
- } else if !self.can_read_lock(key) {
- return Err(TransactionError::AccountInUse);
- }
- }
+ ) -> TransactionResult<()> {
+ self.can_lock_accounts(keys.clone())?;
+ self.lock_accounts(keys);
- for (key, writable) in keys {
- if writable {
- self.lock_write(key);
- } else {
- self.lock_readonly(key);
+ Ok(())
+ }
+
+ /// Lock accounts for all transactions in a batch which don't conflict
+ /// with existing locks. Returns a vector of `TransactionResult` indicating
+ /// success or failure for each transaction in the batch.
+ /// NOTE this is the SIMD83 logic; after the feature is active, it becomes
+ /// the only logic, and this note can be removed with the feature gate.
+ pub fn try_lock_transaction_batch<'a>(
+ &mut self,
+ mut validated_batch_keys: Vec<
+ TransactionResult + Clone>,
+ >,
+ ) -> Vec> {
+ validated_batch_keys.iter_mut().for_each(|validated_keys| {
+ if let Ok(ref keys) = validated_keys {
+ if let Err(e) = self.can_lock_accounts(keys.clone()) {
+ *validated_keys = Err(e);
+ }
}
- }
+ });
- Ok(())
+ validated_batch_keys
+ .into_iter()
+ .map(|available_keys| available_keys.map(|keys| self.lock_accounts(keys)))
+ .collect()
}
/// Unlock the account keys in `keys` after a transaction.
@@ -59,6 +70,33 @@ impl AccountLocks {
}
}
+ fn can_lock_accounts<'a>(
+ &self,
+ keys: impl Iterator
- ,
+ ) -> TransactionResult<()> {
+ for (key, writable) in keys {
+ if writable {
+ if !self.can_write_lock(key) {
+ return Err(TransactionError::AccountInUse);
+ }
+ } else if !self.can_read_lock(key) {
+ return Err(TransactionError::AccountInUse);
+ }
+ }
+
+ Ok(())
+ }
+
+ fn lock_accounts<'a>(&mut self, keys: impl Iterator
- ) {
+ for (key, writable) in keys {
+ if writable {
+ self.lock_write(key);
+ } else {
+ self.lock_readonly(key);
+ }
+ }
+ }
+
#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
fn is_locked_readonly(&self, key: &Pubkey) -> bool {
self.readonly_locks.get(key).is_some_and(|count| *count > 0)
@@ -66,7 +104,7 @@ impl AccountLocks {
#[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
fn is_locked_write(&self, key: &Pubkey) -> bool {
- self.write_locks.contains(key)
+ self.write_locks.get(key).is_some_and(|count| *count > 0)
}
fn can_read_lock(&self, key: &Pubkey) -> bool {
@@ -84,7 +122,7 @@ impl AccountLocks {
}
fn lock_write(&mut self, key: &Pubkey) {
- self.write_locks.insert(*key);
+ *self.write_locks.entry(*key).or_default() += 1;
}
fn unlock_readonly(&mut self, key: &Pubkey) {
@@ -103,11 +141,18 @@ impl AccountLocks {
}
fn unlock_write(&mut self, key: &Pubkey) {
- let removed = self.write_locks.remove(key);
- debug_assert!(
- removed,
- "Attempted to remove a write-lock for a key that wasn't write-locked"
- );
+ if let hash_map::Entry::Occupied(mut occupied_entry) = self.write_locks.entry(*key) {
+ let count = occupied_entry.get_mut();
+ *count -= 1;
+ if *count == 0 {
+ occupied_entry.remove_entry();
+ }
+ } else {
+ debug_assert!(
+ false,
+ "Attempted to remove a write-lock for a key that wasn't write-locked"
+ );
+ }
}
}
@@ -115,7 +160,7 @@ impl AccountLocks {
pub fn validate_account_locks(
account_keys: AccountKeys,
tx_account_lock_limit: usize,
-) -> Result<(), TransactionError> {
+) -> TransactionResult<()> {
if account_keys.len() > tx_account_lock_limit {
Err(TransactionError::TooManyAccountLocks)
} else if has_duplicates(account_keys) {
diff --git a/accounts-db/src/account_storage_reader.rs b/accounts-db/src/account_storage_reader.rs
new file mode 100644
index 00000000000000..355d122cf3c8c0
--- /dev/null
+++ b/accounts-db/src/account_storage_reader.rs
@@ -0,0 +1,416 @@
+use {
+ crate::{
+ account_info::Offset,
+ accounts_db::AccountStorageEntry,
+ accounts_file::{AccountsFile, InternalsForArchive},
+ },
+ solana_clock::Slot,
+ std::{
+ fs::File,
+ io::{self, Read, Seek, SeekFrom},
+ },
+};
+
+/// A wrapper type around `AccountStorageEntry` that implements the `Read` trait.
+/// This type skips over the data in accounts contained in the obsolete accounts structure
+pub struct AccountStorageReader<'a> {
+ sorted_obsolete_accounts: Vec<(Offset, usize)>,
+ current_offset: usize,
+ file: Option,
+ internals: InternalsForArchive<'a>,
+ num_alive_bytes: usize,
+ num_total_bytes: usize,
+}
+
+impl<'a> AccountStorageReader<'a> {
+ /// Creates a new `AccountStorageReader` from an `AccountStorageEntry`.
+ /// The obsolete accounts structure is sorted during initialization.
+ pub fn new(storage: &'a AccountStorageEntry, snapshot_slot: Option) -> io::Result {
+ let internals = storage.accounts.internals_for_archive();
+ let num_total_bytes = storage.accounts.len();
+ let num_alive_bytes = num_total_bytes - storage.get_obsolete_bytes(snapshot_slot);
+
+ let mut sorted_obsolete_accounts = storage.get_obsolete_accounts(snapshot_slot);
+
+ // Tiered storage is not compatible with obsolete acocunts at this time
+ if matches!(storage.accounts, AccountsFile::TieredStorage(_)) {
+ assert!(
+ sorted_obsolete_accounts.is_empty(),
+ "Obsolete accounts should be empty for TieredStorage"
+ );
+ }
+
+ // Convert the length to the size
+ sorted_obsolete_accounts
+ .iter_mut()
+ .for_each(|(_offset, len)| {
+ *len = storage.accounts.calculate_stored_size(*len);
+ });
+
+ sorted_obsolete_accounts
+ .sort_unstable_by(|(a_offset, _), (b_offset, _)| b_offset.cmp(a_offset));
+
+ let file = match internals {
+ InternalsForArchive::Mmap(_internals) => None,
+ InternalsForArchive::FileIo(path) => Some(File::open(path)?),
+ };
+
+ Ok(Self {
+ sorted_obsolete_accounts,
+ current_offset: 0,
+ file,
+ internals,
+ num_alive_bytes,
+ num_total_bytes,
+ })
+ }
+
+ pub fn len(&self) -> usize {
+ self.num_alive_bytes
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl Read for AccountStorageReader<'_> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result {
+ let mut total_read = 0;
+ let buf_len = buf.len();
+
+ while total_read < buf_len {
+ let next_obsolete_account = self.sorted_obsolete_accounts.last();
+ if let Some(&(obsolete_start, obsolete_size)) = next_obsolete_account {
+ if self.current_offset == obsolete_start {
+ self.current_offset += obsolete_size.min(self.num_total_bytes - obsolete_start);
+ self.sorted_obsolete_accounts.pop();
+ continue;
+ }
+ }
+
+ // Cannot read beyond the end of the buffer
+ let bytes_left_in_buffer = buf_len.saturating_sub(total_read);
+
+ // Cannot read beyond the next obsolete account or the end of the file
+ let bytes_to_read_from_file = if let Some((obsolete_start, _)) = next_obsolete_account {
+ obsolete_start.saturating_sub(self.current_offset)
+ } else {
+ self.num_total_bytes.saturating_sub(self.current_offset)
+ };
+
+ let bytes_to_read = bytes_left_in_buffer.min(bytes_to_read_from_file);
+
+ let read_size = match self.internals {
+ InternalsForArchive::Mmap(data) => (&data
+ [self.current_offset..self.current_offset + bytes_to_read])
+ .read(&mut buf[total_read..][..bytes_to_read])?,
+
+ InternalsForArchive::FileIo(_) => {
+ let file = &mut self
+ .file
+ .as_mut()
+ .expect("File is opened during initialization");
+ file.seek(SeekFrom::Start(self.current_offset as u64))?;
+ file.read(&mut buf[total_read..][..bytes_to_read])?
+ }
+ };
+
+ if read_size == 0 {
+ break; // EOF
+ }
+
+ self.current_offset += read_size;
+ total_read += read_size;
+ }
+
+ Ok(total_read)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use {
+ super::*,
+ crate::{
+ accounts_db::{get_temp_accounts_paths, AccountStorageEntry},
+ accounts_file::{AccountsFile, AccountsFileProvider, StorageAccess},
+ },
+ log::*,
+ rand::{rngs::StdRng, seq::SliceRandom, SeedableRng},
+ solana_account::AccountSharedData,
+ solana_pubkey::Pubkey,
+ std::iter,
+ test_case::test_case,
+ };
+
+ fn create_storage_for_storage_reader(
+ slot: Slot,
+ provider: AccountsFileProvider,
+ ) -> (AccountStorageEntry, Vec) {
+ let id = 0;
+ let (temp_dirs, paths) = get_temp_accounts_paths(1).unwrap();
+ let file_size = 1024 * 1024;
+ (
+ AccountStorageEntry::new(&paths[0], slot, id, file_size, provider),
+ temp_dirs,
+ )
+ }
+
+ #[test]
+ #[should_panic(expected = "Obsolete accounts should be empty for TieredStorage")]
+ fn test_account_storage_reader_tiered_storage_one_obsolete_account_should_panic() {
+ let (storage, _temp_dirs) =
+ create_storage_for_storage_reader(0, AccountsFileProvider::HotStorage);
+
+ let account = AccountSharedData::new(1, 10, &Pubkey::new_unique());
+ let account2 = AccountSharedData::new(1, 10, &Pubkey::new_unique());
+ let slot = 0;
+
+ let accounts = [
+ (&Pubkey::new_unique(), &account),
+ (&Pubkey::new_unique(), &account2),
+ ];
+
+ storage.accounts.append_accounts(&(slot, &accounts[..]), 0);
+
+ let offset = 0;
+ // Mark the obsolete accounts in storage
+ let mut size = storage.accounts.get_account_data_lens(&[0]);
+ storage.mark_account_obsolete(offset, size.pop().unwrap(), 0);
+
+ _ = AccountStorageReader::new(&storage, None).unwrap();
+ }
+
+ #[test_case(AccountsFileProvider::AppendVec)]
+ #[test_case(AccountsFileProvider::HotStorage)]
+ fn test_account_storage_reader_no_obsolete_accounts(provider: AccountsFileProvider) {
+ let (storage, _temp_dirs) = create_storage_for_storage_reader(0, provider);
+
+ let account = AccountSharedData::new(1, 10, &Pubkey::default());
+ let account2 = AccountSharedData::new(1, 10, &Pubkey::default());
+ let slot = 0;
+
+ let accounts = [
+ (&Pubkey::new_unique(), &account),
+ (&Pubkey::new_unique(), &account2),
+ ];
+
+ storage.accounts.append_accounts(&(slot, &accounts[..]), 0);
+
+ let reader = AccountStorageReader::new(&storage, None).unwrap();
+ assert_eq!(reader.len(), storage.accounts.len());
+ }
+
+ #[test_case(0, 0, StorageAccess::File)]
+ #[test_case(1, 0, StorageAccess::File)]
+ #[test_case(1, 1, StorageAccess::File)]
+ #[test_case(100, 0, StorageAccess::File)]
+ #[test_case(100, 10, StorageAccess::File)]
+ #[test_case(100, 100, StorageAccess::File)]
+ #[test_case(0, 0, StorageAccess::Mmap)]
+ #[test_case(1, 0, StorageAccess::Mmap)]
+ #[test_case(1, 1, StorageAccess::Mmap)]
+ #[test_case(100, 0, StorageAccess::Mmap)]
+ #[test_case(100, 10, StorageAccess::Mmap)]
+ #[test_case(100, 100, StorageAccess::Mmap)]
+ fn test_account_storage_reader_with_obsolete_accounts(
+ total_accounts: usize,
+ number_of_accounts_to_remove: usize,
+ storage_access: StorageAccess,
+ ) {
+ solana_logger::setup();
+ let (storage, _temp_dirs) =
+ create_storage_for_storage_reader(0, AccountsFileProvider::AppendVec);
+
+ let slot = 0;
+
+ // Create a bunch of accounts and add them to the storage
+ let accounts: Vec<_> =
+ iter::repeat_with(|| AccountSharedData::new(1, 10, &Pubkey::default()))
+ .take(total_accounts)
+ .collect();
+
+ let accounts_to_append: Vec<_> = accounts
+ .into_iter()
+ .map(|account| (Pubkey::new_unique(), account))
+ .collect();
+
+ let offsets = storage
+ .accounts
+ .append_accounts(&(slot, &accounts_to_append[..]), 0);
+
+ // Generate a seed from entropy and log the original seed
+ let seed: u64 = rand::random();
+ info!("Generated seed: {}", seed);
+
+ // Use a seedable RNG with the generated seed for reproducibility
+ let mut rng = StdRng::seed_from_u64(seed);
+
+ let obsolete_account_offset = offsets
+ .map(|offsets| {
+ offsets
+ .offsets
+ .choose_multiple(&mut rng, number_of_accounts_to_remove)
+ .cloned()
+ .collect::>()
+ })
+ .unwrap_or_default();
+
+ assert_eq!(obsolete_account_offset.len(), number_of_accounts_to_remove);
+
+ // Mark the obsolete accounts in storage
+ obsolete_account_offset.into_iter().for_each(|offset| {
+ let mut size = storage.accounts.get_account_data_lens(&[offset]);
+ storage.mark_account_obsolete(offset, size.pop().unwrap(), 0);
+ });
+
+ let storage = storage
+ .reopen_as_readonly(storage_access)
+ .unwrap_or(storage);
+
+ // Assert that storage.accounts was reopened with the specified access type
+ match storage_access {
+ StorageAccess::File => assert!(matches!(
+ storage.accounts.internals_for_archive(),
+ InternalsForArchive::FileIo(_)
+ )),
+ StorageAccess::Mmap => assert!(matches!(
+ storage.accounts.internals_for_archive(),
+ InternalsForArchive::Mmap(_)
+ )),
+ }
+
+ // Create the reader and check the length
+ let mut reader = AccountStorageReader::new(&storage, None).unwrap();
+ let current_len = storage.accounts.len() - storage.get_obsolete_bytes(None);
+ assert_eq!(reader.len(), current_len);
+
+ // Create a temporary directory and a file within it
+ let temp_dir = tempfile::tempdir().unwrap();
+ let temp_file_path = temp_dir.path().join("output_file");
+ let mut output_file = File::create(&temp_file_path).unwrap();
+
+ let bytes_written = io::copy(&mut reader, &mut output_file).unwrap();
+ assert_eq!(bytes_written as usize, reader.len());
+
+ // Close the file
+ drop(output_file);
+
+ // If the number of accounts left is not zero, create a new AccountsFile from the output file
+ // and verify that the number of accounts in the new file is correct
+ if (total_accounts - number_of_accounts_to_remove) != 0 {
+ let (accounts_file, num_accounts) =
+ AccountsFile::new_from_file(temp_file_path, current_len, StorageAccess::File)
+ .unwrap();
+
+ // Verify that the correct number of accounts were found in the file
+ assert_eq!(
+ num_accounts,
+ (total_accounts - number_of_accounts_to_remove)
+ );
+
+ // Create a new AccountStorageEntry from the output file
+ let new_storage =
+ AccountStorageEntry::new_existing(slot, 0, accounts_file, num_accounts);
+
+ // Verify that the new storage has the same length as the reader
+ assert_eq!(new_storage.accounts.len(), reader.len());
+ }
+ }
+
+ #[test]
+ fn test_account_storage_reader_filter_by_slot() {
+ let (storage, _temp_dirs) =
+ create_storage_for_storage_reader(10, AccountsFileProvider::AppendVec);
+ let total_accounts = 30;
+
+ let slot = 0;
+
+ // Create a bunch of accounts and add them to the storage
+ let accounts: Vec<_> =
+ iter::repeat_with(|| AccountSharedData::new(1, 10, &Pubkey::default()))
+ .take(total_accounts)
+ .collect();
+
+ let accounts_to_append: Vec<_> = accounts
+ .into_iter()
+ .map(|account| (Pubkey::new_unique(), account))
+ .collect();
+
+ let offsets = storage
+ .accounts
+ .append_accounts(&(slot, &accounts_to_append[..]), 0);
+
+ // Generate a seed from entropy and log the original seed
+ let seed: u64 = rand::random();
+ info!("Generated seed: {}", seed);
+
+ // Use a seedable RNG with the generated seed for reproducibility
+ let mut rng = StdRng::seed_from_u64(seed);
+
+ let max_offset = offsets
+ .as_ref()
+ .and_then(|offsets| offsets.offsets.iter().max().cloned())
+ .unwrap();
+
+ let mut obsolete_account_offset = offsets
+ .map(|offsets| {
+ offsets
+ .offsets
+ .choose_multiple(&mut rng, total_accounts - 1)
+ .cloned()
+ .collect::>()
+ })
+ .unwrap_or_default();
+
+ // Ensure that the last entry will be marked obsolete at some point
+ if !obsolete_account_offset.contains(&max_offset) {
+ // Replace a random obsolete account with the max offset
+ if let Some(random_index) = obsolete_account_offset.choose_mut(&mut rng) {
+ *random_index = max_offset;
+ }
+ }
+
+ // Mark the obsolete accounts in storage at different slots
+ let mut slot_marked_dead = 0;
+ obsolete_account_offset.into_iter().for_each(|offset| {
+ let mut size = storage.accounts.get_account_data_lens(&[offset]);
+ storage.mark_account_obsolete(offset, size.pop().unwrap(), slot_marked_dead);
+ slot_marked_dead += 1;
+ });
+
+ // Create a temporary directory
+ let temp_dir = tempfile::tempdir().unwrap();
+
+ // Now iterate through all the possible snapshot slots and verify correctness
+ for snapshot_slot in 0..slot_marked_dead {
+ let mut reader = AccountStorageReader::new(&storage, Some(snapshot_slot)).unwrap();
+ let current_len =
+ storage.accounts.len() - storage.get_obsolete_bytes(Some(snapshot_slot));
+ assert_eq!(reader.len(), current_len);
+
+ // Create a file to write the reader's output. It will get deleted by AccountsFile::drop() every
+ // iteration so it does not need a unique name
+ let temp_file_path = temp_dir.path().join("output_file");
+ let mut output_file = File::create(&temp_file_path).unwrap();
+
+ let bytes_written = io::copy(&mut reader, &mut output_file).unwrap();
+ assert_eq!(bytes_written as usize, reader.len());
+
+ // Close the file
+ drop(output_file);
+
+ let (accounts_file, num_accounts) =
+ AccountsFile::new_from_file(temp_file_path, current_len, StorageAccess::File)
+ .unwrap();
+
+ // Create a new AccountStorageEntry from the output file
+ let new_storage =
+ AccountStorageEntry::new_existing(slot, 0, accounts_file, num_accounts);
+
+ // Verify that the new storage has the same length as the reader
+ assert_eq!(new_storage.accounts.len(), reader.len());
+ }
+ }
+}
diff --git a/accounts-db/src/accounts.rs b/accounts-db/src/accounts.rs
index 01c9d75468e10a..9c06ee08305e9a 100644
--- a/accounts-db/src/accounts.rs
+++ b/accounts-db/src/accounts.rs
@@ -566,57 +566,39 @@ impl Accounts {
}
/// This function will prevent multiple threads from modifying the same account state at the
- /// same time
+ /// same time, possibly excluding transactions based on prior results
#[must_use]
- pub fn lock_accounts<'a, Tx: SVMMessage + 'a>(
- &self,
- txs: impl Iterator
- ,
- tx_account_lock_limit: usize,
- ) -> Vec> {
- // Validate the account locks, then get iterator if successful validation.
- let tx_account_locks_results: Vec> = txs
- .map(|tx| {
- validate_account_locks(tx.account_keys(), tx_account_lock_limit)
- .map(|_| TransactionAccountLocksIterator::new(tx))
- })
- .collect();
- self.lock_accounts_inner(tx_account_locks_results)
- }
-
- #[must_use]
- pub fn lock_accounts_with_results<'a>(
+ pub fn lock_accounts<'a>(
&self,
txs: impl Iterator
- ,
results: impl Iterator
- >,
tx_account_lock_limit: usize,
+ relax_intrabatch_account_locks: bool,
) -> Vec> {
- // Validate the account locks, then get iterator if successful validation.
- let tx_account_locks_results: Vec> = txs
+ // Validate the account locks, then get keys and is_writable if successful validation.
+ // We collect to fully evaluate before taking the account_locks mutex.
+ let validated_batch_keys = txs
.zip(results)
- .map(|(tx, result)| match result {
- Ok(()) => validate_account_locks(tx.account_keys(), tx_account_lock_limit)
- .map(|_| TransactionAccountLocksIterator::new(tx)),
- Err(err) => Err(err),
+ .map(|(tx, result)| {
+ result
+ .and_then(|_| validate_account_locks(tx.account_keys(), tx_account_lock_limit))
+ .map(|_| TransactionAccountLocksIterator::new(tx).accounts_with_is_writable())
})
- .collect();
- self.lock_accounts_inner(tx_account_locks_results)
- }
+ .collect::>();
- #[must_use]
- fn lock_accounts_inner(
- &self,
- tx_account_locks_results: Vec>>,
- ) -> Vec> {
let account_locks = &mut self.account_locks.lock().unwrap();
- tx_account_locks_results
- .into_iter()
- .map(|tx_account_locks_result| match tx_account_locks_result {
- Ok(tx_account_locks) => {
- account_locks.try_lock_accounts(tx_account_locks.accounts_with_is_writable())
- }
- Err(err) => Err(err),
- })
- .collect()
+
+ if relax_intrabatch_account_locks {
+ account_locks.try_lock_transaction_batch(validated_batch_keys)
+ } else {
+ validated_batch_keys
+ .into_iter()
+ .map(|result_validated_tx_keys| match result_validated_tx_keys {
+ Ok(validated_tx_keys) => account_locks.try_lock_accounts(validated_tx_keys),
+ Err(e) => Err(e),
+ })
+ .collect()
+ }
}
/// Once accounts are unlocked, new transactions that modify that state can enter the pipeline
@@ -662,15 +644,18 @@ impl Accounts {
mod tests {
use {
super::*,
+ agave_reserved_account_keys::ReservedAccountKeys,
solana_account::{AccountSharedData, WritableAccount},
solana_address_lookup_table_interface::state::LookupTableMeta,
solana_hash::Hash,
+ solana_instruction::{AccountMeta, Instruction},
solana_keypair::Keypair,
solana_message::{
- compiled_instruction::CompiledInstruction, v0::MessageAddressTableLookup, Message,
- MessageHeader,
+ compiled_instruction::CompiledInstruction, v0::MessageAddressTableLookup,
+ LegacyMessage, Message, MessageHeader, SanitizedMessage,
},
solana_sdk_ids::native_loader,
+ solana_signature::Signature,
solana_signer::{signers::Signers, Signer},
solana_transaction::{sanitized::MAX_TX_ACCOUNT_LOCKS, Transaction},
solana_transaction_error::TransactionError,
@@ -680,6 +665,7 @@ mod tests {
sync::atomic::{AtomicBool, AtomicU64, Ordering},
thread, time,
},
+ test_case::test_case,
};
fn new_sanitized_tx(
@@ -694,6 +680,23 @@ mod tests {
))
}
+ fn sanitized_tx_from_metas(accounts: Vec) -> SanitizedTransaction {
+ let instruction = Instruction {
+ accounts,
+ program_id: Pubkey::default(),
+ data: vec![],
+ };
+
+ let message = Message::new(&[instruction], None);
+
+ let sanitized_message = SanitizedMessage::Legacy(LegacyMessage::new(
+ message,
+ &ReservedAccountKeys::empty_key_set(),
+ ));
+
+ SanitizedTransaction::new_for_tests(sanitized_message, vec![Signature::new_unique()], false)
+ }
+
#[test]
fn test_hold_range_in_memory() {
let accounts_db = AccountsDb::default_for_tests();
@@ -895,8 +898,9 @@ mod tests {
assert_eq!(loaded, vec![]);
}
- #[test]
- fn test_lock_accounts_with_duplicates() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_lock_accounts_with_duplicates(relax_intrabatch_account_locks: bool) {
let accounts_db = AccountsDb::new_single_for_tests();
let accounts = Accounts::new(Arc::new(accounts_db));
@@ -911,12 +915,18 @@ mod tests {
};
let tx = new_sanitized_tx(&[&keypair], message, Hash::default());
- let results = accounts.lock_accounts([tx].iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results = accounts.lock_accounts(
+ [tx].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert_eq!(results[0], Err(TransactionError::AccountLoadedTwice));
}
- #[test]
- fn test_lock_accounts_with_too_many_accounts() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_lock_accounts_with_too_many_accounts(relax_intrabatch_account_locks: bool) {
let accounts_db = AccountsDb::new_single_for_tests();
let accounts = Accounts::new(Arc::new(accounts_db));
@@ -939,7 +949,12 @@ mod tests {
};
let txs = vec![new_sanitized_tx(&[&keypair], message, Hash::default())];
- let results = accounts.lock_accounts(txs.iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results = accounts.lock_accounts(
+ txs.iter(),
+ vec![Ok(()); txs.len()].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert_eq!(results, vec![Ok(())]);
accounts.unlock_accounts(txs.iter().zip(&results));
}
@@ -961,13 +976,19 @@ mod tests {
};
let txs = vec![new_sanitized_tx(&[&keypair], message, Hash::default())];
- let results = accounts.lock_accounts(txs.iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results = accounts.lock_accounts(
+ txs.iter(),
+ vec![Ok(()); txs.len()].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert_eq!(results[0], Err(TransactionError::TooManyAccountLocks));
}
}
- #[test]
- fn test_accounts_locks() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_accounts_locks(relax_intrabatch_account_locks: bool) {
let keypair0 = Keypair::new();
let keypair1 = Keypair::new();
let keypair2 = Keypair::new();
@@ -995,7 +1016,12 @@ mod tests {
instructions,
);
let tx = new_sanitized_tx(&[&keypair0], message, Hash::default());
- let results0 = accounts.lock_accounts([tx.clone()].iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results0 = accounts.lock_accounts(
+ [tx.clone()].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert_eq!(results0, vec![Ok(())]);
assert!(accounts
@@ -1025,7 +1051,12 @@ mod tests {
);
let tx1 = new_sanitized_tx(&[&keypair1], message, Hash::default());
let txs = vec![tx0, tx1];
- let results1 = accounts.lock_accounts(txs.iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results1 = accounts.lock_accounts(
+ txs.iter(),
+ vec![Ok(()); txs.len()].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert_eq!(
results1,
vec![
@@ -1051,7 +1082,12 @@ mod tests {
instructions,
);
let tx = new_sanitized_tx(&[&keypair1], message, Hash::default());
- let results2 = accounts.lock_accounts([tx].iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results2 = accounts.lock_accounts(
+ [tx].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert_eq!(
results2,
vec![Ok(())] // Now keypair1 account can be locked as writable
@@ -1065,8 +1101,9 @@ mod tests {
.is_locked_readonly(&keypair1.pubkey()));
}
- #[test]
- fn test_accounts_locks_multithreaded() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_accounts_locks_multithreaded(relax_intrabatch_account_locks: bool) {
let counter = Arc::new(AtomicU64::new(0));
let exit = Arc::new(AtomicBool::new(false));
@@ -1113,9 +1150,12 @@ mod tests {
let exit_clone = exit.clone();
thread::spawn(move || loop {
let txs = vec![writable_tx.clone()];
- let results = accounts_clone
- .clone()
- .lock_accounts(txs.iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results = accounts_clone.clone().lock_accounts(
+ txs.iter(),
+ vec![Ok(()); txs.len()].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
for result in results.iter() {
if result.is_ok() {
counter_clone.clone().fetch_add(1, Ordering::Release);
@@ -1129,9 +1169,12 @@ mod tests {
let counter_clone = counter;
for _ in 0..5 {
let txs = vec![readonly_tx.clone()];
- let results = accounts_arc
- .clone()
- .lock_accounts(txs.iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results = accounts_arc.clone().lock_accounts(
+ txs.iter(),
+ vec![Ok(()); txs.len()].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
if results[0].is_ok() {
let counter_value = counter_clone.clone().load(Ordering::Acquire);
thread::sleep(time::Duration::from_millis(50));
@@ -1143,8 +1186,9 @@ mod tests {
exit.store(true, Ordering::Relaxed);
}
- #[test]
- fn test_demote_program_write_locks() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_demote_program_write_locks(relax_intrabatch_account_locks: bool) {
let keypair0 = Keypair::new();
let keypair1 = Keypair::new();
let keypair2 = Keypair::new();
@@ -1172,7 +1216,12 @@ mod tests {
instructions,
);
let tx = new_sanitized_tx(&[&keypair0], message, Hash::default());
- let results0 = accounts.lock_accounts([tx].iter(), MAX_TX_ACCOUNT_LOCKS);
+ let results0 = accounts.lock_accounts(
+ [tx].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
assert!(results0[0].is_ok());
// Instruction program-id account demoted to readonly
@@ -1208,8 +1257,9 @@ mod tests {
}
}
- #[test]
- fn test_accounts_locks_with_results() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_accounts_locks_with_results(relax_intrabatch_account_locks: bool) {
let keypair0 = Keypair::new();
let keypair1 = Keypair::new();
let keypair2 = Keypair::new();
@@ -1265,10 +1315,11 @@ mod tests {
Ok(()),
];
- let results = accounts.lock_accounts_with_results(
+ let results = accounts.lock_accounts(
txs.iter(),
qos_results.into_iter(),
MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
);
assert_eq!(
@@ -1294,6 +1345,94 @@ mod tests {
.is_locked_write(&keypair2.pubkey()));
}
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_accounts_locks_intrabatch_conflicts(relax_intrabatch_account_locks: bool) {
+ let pubkey = Pubkey::new_unique();
+ let account_data = AccountSharedData::new(1, 0, &Pubkey::default());
+ let accounts_db = Arc::new(AccountsDb::new_single_for_tests());
+ accounts_db.store_for_tests(
+ 0,
+ &[
+ (&Pubkey::default(), &account_data),
+ (&pubkey, &account_data),
+ ],
+ );
+
+ let r_tx = sanitized_tx_from_metas(vec![AccountMeta {
+ pubkey,
+ is_writable: false,
+ is_signer: false,
+ }]);
+
+ let w_tx = sanitized_tx_from_metas(vec![AccountMeta {
+ pubkey,
+ is_writable: true,
+ is_signer: false,
+ }]);
+
+ // one w tx alone always works
+ let accounts = Accounts::new(accounts_db.clone());
+ let results = accounts.lock_accounts(
+ [w_tx.clone()].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
+
+ assert_eq!(results, vec![Ok(())]);
+
+ // wr conflict cross-batch always fails
+ let results = accounts.lock_accounts(
+ [r_tx.clone()].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
+
+ assert_eq!(results, vec![Err(TransactionError::AccountInUse)]);
+
+ // ww conflict cross-batch always fails
+ let results = accounts.lock_accounts(
+ [w_tx.clone()].iter(),
+ [Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
+
+ assert_eq!(results, vec![Err(TransactionError::AccountInUse)]);
+
+ // wr conflict in-batch succeeds or fails based on feature
+ let accounts = Accounts::new(accounts_db.clone());
+ let results = accounts.lock_accounts(
+ [w_tx.clone(), r_tx.clone()].iter(),
+ [Ok(()), Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
+
+ if relax_intrabatch_account_locks {
+ assert_eq!(results, vec![Ok(()), Ok(())]);
+ } else {
+ assert_eq!(results, vec![Ok(()), Err(TransactionError::AccountInUse)]);
+ }
+
+ // ww conflict in-batch succeeds or fails based on feature
+ let accounts = Accounts::new(accounts_db.clone());
+ let results = accounts.lock_accounts(
+ [w_tx.clone(), r_tx.clone()].iter(),
+ [Ok(()), Ok(())].into_iter(),
+ MAX_TX_ACCOUNT_LOCKS,
+ relax_intrabatch_account_locks,
+ );
+
+ if relax_intrabatch_account_locks {
+ assert_eq!(results, vec![Ok(()), Ok(())]);
+ } else {
+ assert_eq!(results, vec![Ok(()), Err(TransactionError::AccountInUse)]);
+ }
+ }
+
#[test]
fn huge_clean() {
solana_logger::setup();
diff --git a/accounts-db/src/accounts_cache.rs b/accounts-db/src/accounts_cache.rs
index 12fb4e0289a6a6..f46c836badf384 100644
--- a/accounts-db/src/accounts_cache.rs
+++ b/accounts-db/src/accounts_cache.rs
@@ -23,16 +23,24 @@ pub struct SlotCache {
same_account_writes: AtomicU64,
same_account_writes_size: AtomicU64,
unique_account_writes_size: AtomicU64,
+ /// The size of account data stored in `cache` (just this slot), in bytes
size: AtomicU64,
+ /// The size of account data stored in the whole AccountsCache, in bytes
total_size: Arc,
is_frozen: AtomicBool,
+ /// The number of accounts stored in `cache` (just this slot)
+ accounts_count: AtomicU64,
+ /// The number of accounts stored in the whole AccountsCache
+ total_accounts_count: Arc,
}
impl Drop for SlotCache {
fn drop(&mut self) {
- // broader cache no longer holds our size in memory
+ // broader cache no longer holds our size/counts in memory
self.total_size
- .fetch_sub(self.size.load(Ordering::Relaxed), Ordering::Relaxed);
+ .fetch_sub(*self.size.get_mut(), Ordering::Relaxed);
+ self.total_accounts_count
+ .fetch_sub(*self.accounts_count.get_mut(), Ordering::Relaxed);
}
}
@@ -55,7 +63,12 @@ impl SlotCache {
self.unique_account_writes_size.load(Ordering::Relaxed),
i64
),
- ("size", self.size.load(Ordering::Relaxed), i64)
+ ("size", self.size.load(Ordering::Relaxed), i64),
+ (
+ "accounts_count",
+ self.accounts_count.load(Ordering::Relaxed),
+ i64
+ )
);
}
@@ -88,6 +101,8 @@ impl SlotCache {
self.total_size.fetch_add(data_len, Ordering::Relaxed);
self.unique_account_writes_size
.fetch_add(data_len, Ordering::Relaxed);
+ self.accounts_count.fetch_add(1, Ordering::Relaxed);
+ self.total_accounts_count.fetch_add(1, Ordering::Relaxed);
}
item
}
@@ -153,7 +168,10 @@ pub struct AccountsCache {
// could have triggered a flush of this slot already
maybe_unflushed_roots: RwLock>,
max_flushed_root: AtomicU64,
+ /// The size of account data stored in the whole AccountsCache, in bytes
total_size: Arc,
+ /// The number of accounts stored in the whole AccountsCache
+ total_accounts_counts: Arc,
}
impl AccountsCache {
@@ -166,19 +184,10 @@ impl AccountsCache {
size: AtomicU64::default(),
total_size: Arc::clone(&self.total_size),
is_frozen: AtomicBool::default(),
+ accounts_count: AtomicU64::new(0),
+ total_accounts_count: Arc::clone(&self.total_accounts_counts),
})
}
- fn unique_account_writes_size(&self) -> u64 {
- self.cache
- .iter()
- .map(|item| {
- let slot_cache = item.value();
- slot_cache
- .unique_account_writes_size
- .load(Ordering::Relaxed)
- })
- .sum()
- }
pub fn size(&self) -> u64 {
self.total_size.load(Ordering::Relaxed)
}
@@ -191,12 +200,12 @@ impl AccountsCache {
i64
),
("num_slots", self.cache.len(), i64),
+ ("total_size", self.size(), i64),
(
- "total_unique_writes_size",
- self.unique_account_writes_size(),
+ "total_accounts_count",
+ self.total_accounts_counts.load(Ordering::Relaxed),
i64
),
- ("total_size", self.size(), i64),
);
}
diff --git a/accounts-db/src/accounts_db.rs b/accounts-db/src/accounts_db.rs
index 1fde2b936d2069..fab7eb290f7323 100644
--- a/accounts-db/src/accounts_db.rs
+++ b/accounts-db/src/accounts_db.rs
@@ -1071,6 +1071,16 @@ pub struct AccountStorageEntry {
/// account as "dead" twice. However, this should be fine. It just makes
/// shrink more likely to visit this storage.
zero_lamport_single_ref_offsets: RwLock>,
+
+ /// Obsolete Accounts. These are accounts that are still present in the storage
+ /// but should be ignored during rebuild. They have been removed
+ /// from the accounts index, so they will not be picked up by scan.
+ /// Slot is the slot at which the account is no longer needed.
+ /// Two scenarios cause an account entry to be marked obsolete
+ /// 1. The account was rewritten to a newer slot
+ /// 2. The account was set to zero lamports and is older than the last
+ /// full snapshot. In this case, slot is set to the snapshot slot
+ obsolete_accounts: RwLock>,
}
impl AccountStorageEntry {
@@ -1092,10 +1102,12 @@ impl AccountStorageEntry {
count_and_status: SeqLock::new((0, AccountStorageStatus::Available)),
alive_bytes: AtomicUsize::new(0),
zero_lamport_single_ref_offsets: RwLock::default(),
+ obsolete_accounts: RwLock::default(),
}
}
/// open a new instance of the storage that is readonly
+ #[cfg_attr(feature = "dev-context-only-utils", qualifiers(pub))]
fn reopen_as_readonly(&self, storage_access: StorageAccess) -> Option {
if storage_access != StorageAccess::File {
// if we are only using mmap, then no reason to re-open
@@ -1110,6 +1122,7 @@ impl AccountStorageEntry {
alive_bytes: AtomicUsize::new(self.alive_bytes()),
accounts,
zero_lamport_single_ref_offsets: RwLock::default(),
+ obsolete_accounts: RwLock::new(self.obsolete_accounts.read().unwrap().clone()),
})
}
@@ -1126,6 +1139,7 @@ impl AccountStorageEntry {
count_and_status: SeqLock::new((0, AccountStorageStatus::Available)),
alive_bytes: AtomicUsize::new(0),
zero_lamport_single_ref_offsets: RwLock::default(),
+ obsolete_accounts: RwLock::default(),
}
}
@@ -1162,6 +1176,44 @@ impl AccountStorageEntry {
self.alive_bytes.load(Ordering::Acquire)
}
+ /// Marks the account at the given offset as obsolete
+ pub fn mark_account_obsolete(&self, offset: Offset, data_len: usize, slot: Slot) {
+ self.obsolete_accounts
+ .write()
+ .unwrap()
+ .push((offset, data_len, slot));
+ }
+
+ /// Returns the accounts that were marked obsolete as of the passed in slot
+ /// or earlier. If slot is None, then slot will be assumed to be the max root
+ /// and all obsolete accounts will be returned.
+ pub fn get_obsolete_accounts(&self, slot: Option) -> Vec<(Offset, usize)> {
+ self.obsolete_accounts
+ .read()
+ .unwrap()
+ .iter()
+ .filter(|(_, _, obsolete_slot)| slot.is_none_or(|s| *obsolete_slot <= s))
+ .map(|(offset, data_len, _)| (*offset, *data_len))
+ .collect()
+ }
+
+ /// Returns the number of bytes that were marked obsolete as of the passed
+ /// in slot or earlier. If slot is None, then slot will be assumed to be the
+ /// max root, and all obsolete bytes will be returned.
+ pub fn get_obsolete_bytes(&self, slot: Option) -> usize {
+ let obsolete_accounts = self.obsolete_accounts.read().unwrap();
+ let obsolete_bytes = obsolete_accounts
+ .iter()
+ .filter(|(_, _, obsolete_slot)| slot.is_none_or(|s| *obsolete_slot <= s))
+ .map(|(offset, data_len, _)| {
+ self.accounts
+ .calculate_stored_size(*data_len)
+ .min(self.accounts.len() - offset)
+ })
+ .sum();
+ obsolete_bytes
+ }
+
/// Return true if offset is "new" and inserted successfully. Otherwise,
/// return false if the offset exists already.
fn insert_zero_lamport_single_ref_account_offset(&self, offset: usize) -> bool {
diff --git a/accounts-db/src/accounts_index_storage.rs b/accounts-db/src/accounts_index_storage.rs
index 8e5353e6d4a94b..f91a55bd12b818 100644
--- a/accounts-db/src/accounts_index_storage.rs
+++ b/accounts-db/src/accounts_index_storage.rs
@@ -63,10 +63,18 @@ impl BgThreads {
can_advance_age: bool,
exit: Arc,
) -> Self {
+ let is_disk_index_enabled = storage.is_disk_index_enabled();
+ let num_threads = if is_disk_index_enabled {
+ threads.get()
+ } else {
+ // no disk index, so only need 1 thread to report stats
+ 1
+ };
+
// stop signal used for THIS batch of bg threads
let local_exit = Arc::new(AtomicBool::default());
let handles = Some(
- (0..threads.get())
+ (0..num_threads)
.map(|idx| {
// the first thread we start is special
let can_advance_age = can_advance_age && idx == 0;
diff --git a/accounts-db/src/append_vec.rs b/accounts-db/src/append_vec.rs
index 0afbb31f1ff74d..d3431bda189a7f 100644
--- a/accounts-db/src/append_vec.rs
+++ b/accounts-db/src/append_vec.rs
@@ -1047,16 +1047,21 @@ impl AppendVec {
} else if STORE_META_OVERHEAD + data_len <= BUFFER_SIZE {
reader.set_required_data_len(STORE_META_OVERHEAD + data_len);
} else {
- const MAX_CAPACITY: usize =
- STORE_META_OVERHEAD + MAX_PERMITTED_DATA_LENGTH as usize;
- if data_overflow_buffer.is_empty() {
- // Reserve to worst case to avoid multiple reallocations.
- data_overflow_buffer.reserve_exact(MAX_CAPACITY);
- // SAFETY: we only write to the uninitialized portion of the buffer via `copy_from_slice` and `read_into_buffer`.
+ const MAX_CAPACITY: usize = MAX_PERMITTED_DATA_LENGTH as usize;
+ // 128KiB covers a reasonably large distribution of typical account sizes.
+ // In a recent sample, 99.98% of accounts' data lengths were less than or equal to 128KiB.
+ const MIN_CAPACITY: usize = 1024 * 128;
+ let capacity = data_overflow_buffer.capacity();
+ if data_len > capacity {
+ let next_cap = data_len
+ .next_power_of_two()
+ .clamp(MIN_CAPACITY, MAX_CAPACITY);
+ data_overflow_buffer.reserve_exact(next_cap - capacity);
+ // SAFETY: We only write to the uninitialized portion of the buffer via `copy_from_slice` and `read_into_buffer`.
// Later, we ensure we only read from the initialized portion of the buffer.
unsafe {
- data_overflow_buffer.set_len(MAX_CAPACITY);
- };
+ data_overflow_buffer.set_len(next_cap);
+ }
}
// Copy already read data to overflow buffer.
@@ -1603,14 +1608,6 @@ pub mod tests {
impl AppendVec {
/// return how many accounts in the storage
fn accounts_count(&self) -> usize {
- let mut count = 0;
- self.scan_accounts_stored_meta(|_| {
- count += 1;
- });
- count
- }
-
- fn store_accounts_no_data_count(&self) -> usize {
let mut count = 0;
self.scan_stored_accounts_no_data(|_| {
count += 1;
@@ -1726,13 +1723,12 @@ pub mod tests {
assert_eq!(av.get_account_test(indexes[sample]).unwrap(), account);
}
trace!("random read time: {} ms", now.elapsed().as_millis());
-
- let now = Instant::now();
assert_eq!(indexes.len(), size);
assert_eq!(indexes[0], 0);
- let mut sample = 0;
assert_eq!(av.accounts_count(), size);
- assert_eq!(av.store_accounts_no_data_count(), size);
+
+ let mut sample = 0;
+ let now = Instant::now();
av.scan_accounts_stored_meta(|v| {
let account = create_test_account(sample + 1);
let recovered = v.to_account_shared_data();
diff --git a/accounts-db/src/blockhash_queue.rs b/accounts-db/src/blockhash_queue.rs
index ba6bc2d111a3b6..bc7ff77d4c145a 100644
--- a/accounts-db/src/blockhash_queue.rs
+++ b/accounts-db/src/blockhash_queue.rs
@@ -144,7 +144,7 @@ impl BlockhashQueue {
#[deprecated(
since = "2.0.0",
- note = "Please use `solana_program::clock::MAX_PROCESSING_AGE`"
+ note = "Please use `solana_clock::MAX_PROCESSING_AGE`"
)]
pub fn get_max_age(&self) -> usize {
self.max_age
diff --git a/accounts-db/src/bucket_map_holder_stats.rs b/accounts-db/src/bucket_map_holder_stats.rs
index c2b7616cf47c73..ae9835d2ff53e5 100644
--- a/accounts-db/src/bucket_map_holder_stats.rs
+++ b/accounts-db/src/bucket_map_holder_stats.rs
@@ -225,7 +225,7 @@ impl BucketMapHolderStats {
// sum of elapsed time in each thread
let mut thread_time_elapsed_ms = elapsed_ms * storage.threads as u64;
- if disk.is_some() {
+ if storage.is_disk_index_enabled() {
if was_startup {
// these stats only apply at startup
datapoint_info!(
diff --git a/accounts-db/src/lib.rs b/accounts-db/src/lib.rs
index 7650059f793d53..8e4f4ffee45ea1 100644
--- a/accounts-db/src/lib.rs
+++ b/accounts-db/src/lib.rs
@@ -4,6 +4,7 @@
pub mod account_info;
pub mod account_locks;
pub mod account_storage;
+pub mod account_storage_reader;
pub mod accounts;
mod accounts_cache;
pub mod accounts_db;
diff --git a/accounts-db/src/read_only_accounts_cache.rs b/accounts-db/src/read_only_accounts_cache.rs
index 339362a137cb9e..a9bb230dfc27df 100644
--- a/accounts-db/src/read_only_accounts_cache.rs
+++ b/accounts-db/src/read_only_accounts_cache.rs
@@ -380,12 +380,11 @@ impl ReadOnlyAccountsCache {
}
let key = key_to_evict.expect("eviction sample should not be empty");
- #[cfg(not(feature = "dev-context-only-utils"))]
- Self::do_remove(&key, cache, data_size);
+ let _entry = Self::do_remove(&key, cache, data_size);
#[cfg(feature = "dev-context-only-utils")]
{
- let entry = Self::do_remove(&key, cache, data_size);
- callback(&key, entry.unwrap());
+ #[allow(clippy::used_underscore_binding)]
+ callback(&key, _entry.unwrap());
}
num_evicts = num_evicts.saturating_add(1);
}
diff --git a/accounts-db/store-histogram/Cargo.toml b/accounts-db/store-histogram/Cargo.toml
index 75cdea3eb1f362..e762b25c087b2b 100644
--- a/accounts-db/store-histogram/Cargo.toml
+++ b/accounts-db/store-histogram/Cargo.toml
@@ -9,9 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[features]
+dev-context-only-utils = []
+
[dependencies]
clap = { workspace = true }
solana-version = { workspace = true }
-
-[features]
-dev-context-only-utils = []
diff --git a/accounts-db/store-tool/Cargo.toml b/accounts-db/store-tool/Cargo.toml
index 506758e0c01a9e..7b2c8c2e79706d 100644
--- a/accounts-db/store-tool/Cargo.toml
+++ b/accounts-db/store-tool/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[features]
+dev-context-only-utils = []
+
[dependencies]
ahash = { workspace = true }
clap = { workspace = true }
@@ -18,6 +21,3 @@ solana-accounts-db = { workspace = true, features = ["dev-context-only-utils"] }
solana-pubkey = { workspace = true }
solana-system-interface = { workspace = true }
solana-version = { workspace = true }
-
-[features]
-dev-context-only-utils = []
diff --git a/banking-bench/Cargo.toml b/banking-bench/Cargo.toml
index aa9f23ae452163..318f8ce3e0ca66 100644
--- a/banking-bench/Cargo.toml
+++ b/banking-bench/Cargo.toml
@@ -8,6 +8,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
agave-banking-stage-ingress-types = { workspace = true }
assert_matches = { workspace = true }
@@ -39,9 +45,3 @@ solana-time-utils = { workspace = true }
solana-tpu-client = { workspace = true }
solana-transaction = { workspace = true }
solana-version = { workspace = true }
-
-[features]
-dev-context-only-utils = []
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/banks-client/Cargo.toml b/banks-client/Cargo.toml
index cebe3d155d13cf..9749ef89482ea4 100644
--- a/banks-client/Cargo.toml
+++ b/banks-client/Cargo.toml
@@ -9,15 +9,27 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_banks_client"
+
[dependencies]
borsh = { workspace = true }
futures = { workspace = true }
-solana-account = { workspace = true }
+solana-account = { workspace = true, features = ["bincode"] }
solana-banks-interface = { workspace = true }
+solana-clock = { workspace = true }
solana-commitment-config = { workspace = true }
+solana-hash = { workspace = true }
solana-message = { workspace = true }
-solana-program = { workspace = true }
+solana-program-pack = { workspace = true }
+solana-pubkey = { workspace = true }
+solana-rent = { workspace = true }
solana-signature = { workspace = true }
+solana-sysvar = { workspace = true, features = ["bincode"] }
solana-transaction = { workspace = true }
solana-transaction-context = { workspace = true }
solana-transaction-error = { workspace = true }
@@ -32,10 +44,3 @@ solana-pubkey = { workspace = true }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
solana-signer = { workspace = true }
solana-system-interface = { workspace = true }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_banks_client"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/banks-client/src/lib.rs b/banks-client/src/lib.rs
index 9f5f22dce16acd..6068666f18f9fa 100644
--- a/banks-client/src/lib.rs
+++ b/banks-client/src/lib.rs
@@ -17,12 +17,15 @@ use {
BanksRequest, BanksResponse, BanksTransactionResultWithMetadata,
BanksTransactionResultWithSimulation,
},
+ solana_clock::Slot,
solana_commitment_config::CommitmentLevel,
+ solana_hash::Hash,
solana_message::Message,
- solana_program::{
- clock::Slot, hash::Hash, program_pack::Pack, pubkey::Pubkey, rent::Rent, sysvar::Sysvar,
- },
+ solana_program_pack::Pack,
+ solana_pubkey::Pubkey,
+ solana_rent::Rent,
solana_signature::Signature,
+ solana_sysvar::Sysvar,
solana_transaction::versioned::VersionedTransaction,
tarpc::{
client::{self, NewClient, RequestDispatch},
diff --git a/banks-interface/Cargo.toml b/banks-interface/Cargo.toml
index 8dc973d31e5dc7..a1178a7bfc54a9 100644
--- a/banks-interface/Cargo.toml
+++ b/banks-interface/Cargo.toml
@@ -9,10 +9,17 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_banks_interface"
+
[dependencies]
serde = { workspace = true }
serde_derive = { workspace = true }
-solana-account = { workspace = true }
+solana-account = { workspace = true, features = [ "serde" ] }
solana-clock = { workspace = true }
solana-commitment-config = { workspace = true, features = [ "serde" ] }
solana-hash = { workspace = true }
@@ -20,13 +27,6 @@ solana-message = { workspace = true, features = [ "serde" ] }
solana-pubkey = { workspace = true }
solana-signature = { workspace = true, features = [ "serde" ] }
solana-transaction = { workspace = true, features = [ "serde" ] }
-solana-transaction-context = { workspace = true }
+solana-transaction-context = { workspace = true, features = [ "serde" ] }
solana-transaction-error = { workspace = true, features = [ "serde" ] }
tarpc = { workspace = true, features = ["full"] }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_banks_interface"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/banks-interface/src/lib.rs b/banks-interface/src/lib.rs
index c668a598af5fe6..c2cff6aa6b0295 100644
--- a/banks-interface/src/lib.rs
+++ b/banks-interface/src/lib.rs
@@ -38,6 +38,7 @@ pub struct TransactionStatus {
pub struct TransactionSimulationDetails {
pub logs: Vec,
pub units_consumed: u64,
+ pub loaded_accounts_data_size: u32,
pub return_data: Option,
pub inner_instructions: Option>,
}
diff --git a/banks-server/Cargo.toml b/banks-server/Cargo.toml
index d5ad0ce8358dff..3cd5fc9ca75a47 100644
--- a/banks-server/Cargo.toml
+++ b/banks-server/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_banks_server"
+
[dependencies]
agave-feature-set = { workspace = true }
bincode = { workspace = true }
@@ -32,10 +39,3 @@ solana-transaction-error = { workspace = true }
tarpc = { workspace = true, features = ["full"] }
tokio = { workspace = true, features = ["full"] }
tokio-serde = { workspace = true, features = ["bincode"] }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_banks_server"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/banks-server/src/banks_server.rs b/banks-server/src/banks_server.rs
index 1a54f6634bffc8..d5a1e0dfa938d6 100644
--- a/banks-server/src/banks_server.rs
+++ b/banks-server/src/banks_server.rs
@@ -188,6 +188,7 @@ fn simulate_transaction(
logs,
post_simulation_accounts: _,
units_consumed,
+ loaded_accounts_data_size,
return_data,
inner_instructions,
} = bank.simulate_transaction_unchecked(&sanitized_transaction, true);
@@ -195,6 +196,7 @@ fn simulate_transaction(
let simulation_details = TransactionSimulationDetails {
logs,
units_consumed,
+ loaded_accounts_data_size,
return_data,
inner_instructions,
};
diff --git a/bench-streamer/Cargo.toml b/bench-streamer/Cargo.toml
index 2af7ec8f39be94..70c97e1cf4ab6c 100644
--- a/bench-streamer/Cargo.toml
+++ b/bench-streamer/Cargo.toml
@@ -8,12 +8,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
clap = { version = "3.1.5", features = ["cargo"] }
crossbeam-channel = { workspace = true }
solana-net-utils = { workspace = true }
solana-streamer = { workspace = true }
solana-version = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/bench-tps/Cargo.toml b/bench-tps/Cargo.toml
index ec8943227b4e24..6c7ee5fee062b5 100644
--- a/bench-tps/Cargo.toml
+++ b/bench-tps/Cargo.toml
@@ -8,6 +8,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
chrono = { workspace = true }
clap = { workspace = true }
@@ -74,9 +80,3 @@ solana-sdk-ids = { workspace = true }
solana-test-validator = { workspace = true }
solana-tps-client = { workspace = true, features = ["bank-client"] }
tempfile = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = []
diff --git a/bench-vote/Cargo.toml b/bench-vote/Cargo.toml
index 5241b029c7bc14..61b8bf6cbef9cb 100644
--- a/bench-vote/Cargo.toml
+++ b/bench-vote/Cargo.toml
@@ -8,6 +8,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
bincode = { workspace = true }
clap = { workspace = true }
@@ -26,6 +29,3 @@ solana-streamer = { workspace = true }
solana-transaction = { workspace = true }
solana-version = { workspace = true }
solana-vote-program = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/bloom/Cargo.toml b/bloom/Cargo.toml
index e7c33801d26aee..93f4520c747c0e 100644
--- a/bloom/Cargo.toml
+++ b/bloom/Cargo.toml
@@ -9,6 +9,20 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_bloom"
+
+[features]
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-hash/frozen-abi",
+]
+
[dependencies]
bv = { workspace = true, features = ["serde"] }
fnv = { workspace = true }
@@ -30,19 +44,5 @@ solana-hash = { workspace = true }
solana-sha256-hasher = { workspace = true }
solana-signature = { workspace = true, features = ["std"] }
-[lib]
-crate-type = ["lib"]
-name = "solana_bloom"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-hash/frozen-abi",
-]
-
[lints]
workspace = true
diff --git a/bucket_map/Cargo.toml b/bucket_map/Cargo.toml
index a21ba0fedb6683..55bea8fafbbaec 100644
--- a/bucket_map/Cargo.toml
+++ b/bucket_map/Cargo.toml
@@ -10,6 +10,10 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[lib]
+crate-type = ["lib"]
+name = "solana_bucket_map"
+
[dependencies]
bv = { workspace = true, features = ["serde"] }
bytemuck = { workspace = true }
@@ -29,9 +33,5 @@ rayon = { workspace = true }
solana-logger = { workspace = true }
solana-pubkey = { workspace = true, features = ["rand"] }
-[lib]
-crate-type = ["lib"]
-name = "solana_bucket_map"
-
[[bench]]
name = "bucket_map"
diff --git a/builtins-default-costs/Cargo.toml b/builtins-default-costs/Cargo.toml
index 159edf3c7ba549..f7f0e85cc02c56 100644
--- a/builtins-default-costs/Cargo.toml
+++ b/builtins-default-costs/Cargo.toml
@@ -9,6 +9,18 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+# Add additional builtin programs here
+
+[lib]
+crate-type = ["lib"]
+name = "solana_builtins_default_costs"
+
+[features]
+frozen-abi = ["dep:solana-frozen-abi", "solana-vote-program/frozen-abi"]
+dev-context-only-utils = []
+
[dependencies]
agave-feature-set = { workspace = true }
ahash = { workspace = true }
@@ -24,25 +36,10 @@ solana-sdk-ids = { workspace = true }
solana-stake-program = { workspace = true }
solana-system-program = { workspace = true }
solana-vote-program = { workspace = true }
-# Add additional builtin programs here
-
-[lib]
-crate-type = ["lib"]
-name = "solana_builtins_default_costs"
[dev-dependencies]
rand = "0.8.5"
static_assertions = { workspace = true }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "solana-vote-program/frozen-abi",
-]
-dev-context-only-utils = []
-
[lints]
workspace = true
diff --git a/cargo-registry/Cargo.toml b/cargo-registry/Cargo.toml
index d91148e1f2790d..907c49040c57ed 100644
--- a/cargo-registry/Cargo.toml
+++ b/cargo-registry/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
clap = { workspace = true }
flate2 = { workspace = true }
@@ -38,9 +44,3 @@ tokio = { workspace = true, features = ["full"] }
toml = { workspace = true }
[dev-dependencies]
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = []
diff --git a/ci/buildkite-pipeline.sh b/ci/buildkite-pipeline.sh
index f71030cbe1b840..7623897b9d737f 100755
--- a/ci/buildkite-pipeline.sh
+++ b/ci/buildkite-pipeline.sh
@@ -191,6 +191,24 @@ all_test_steps() {
# Full test suite
.buildkite/scripts/build-stable.sh >> "$output_file"
+ # crate publish simulation
+ if affects \
+ Cargo.lock$ \
+ Cargo.toml$ \
+ ^ci/publish-crate.sh \
+ ; then
+ cat >> "$output_file" <<"EOF"
+ - command: "ci/publish-crate.sh --dry-run"
+ name: "publish-crate-simulation"
+ timeout_in_minutes: 180
+ artifact_paths: "log-*.txt"
+ env:
+ CRATE_PUBLISH_TEST: "true"
+ agents:
+ queue: "check"
+EOF
+ fi
+
# Docs tests
if affects \
.rs$ \
diff --git a/ci/cargo/config.toml b/ci/cargo/config.toml
new file mode 100644
index 00000000000000..18a2f71838eb8e
--- /dev/null
+++ b/ci/cargo/config.toml
@@ -0,0 +1,9 @@
+[target.x86_64-unknown-linux-gnu]
+# When building for linux, target the minimal supported CPU
+rustflags = ["-Ctarget-cpu=x86-64-v2"]
+
+# registry configuration for crate publish test
+[registries.kellnr]
+index = "sparse+http://127.0.0.1:8000/api/v1/crates/"
+credential-provider = ["cargo:token"]
+token = "Zy9HhJ02RJmg0GCrgLfaCVfU6IwDfhXD"
diff --git a/ci/change-crate-deps.py b/ci/change-crate-deps.py
new file mode 100755
index 00000000000000..9ce59bdfd00a65
--- /dev/null
+++ b/ci/change-crate-deps.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+# This script:
+# - searches given manifest file for solana / agave dependencies
+# - modifies each found line in the file by adding a custom registry parameter
+# - writes the output back to the given manifest file
+#
+
+import json
+import os
+import subprocess
+import sys
+
+if len(sys.argv) != 3:
+ print('Usage: %s ' % sys.argv[0])
+
+real_file = os.path.realpath(__file__)
+ci_path = os.path.dirname(real_file)
+src_root = os.path.dirname(ci_path)
+cargo_toml = os.path.join(src_root, sys.argv[1])
+pkg_name = sys.argv[2]
+version = os.environ.get('CI_TAG')
+
+
+def load_metadata():
+ cmd = f'{src_root}/cargo metadata --no-deps --format-version=1'
+ return json.loads(subprocess.Popen(
+ cmd, shell=True, stdout=subprocess.PIPE).communicate()[0])
+
+
+def get_pkg_deps(package_name):
+ metadata = load_metadata()
+ dependency_graph = dict()
+
+ for pkg in metadata['packages']:
+ dependency_graph[pkg['name']] = [
+ x['name'] for x in pkg['dependencies'] if x['name'].startswith(('solana', 'agave')) and x['source'] is None
+ ]
+ return dependency_graph[package_name]
+
+
+with open(cargo_toml, 'rb', 0) as file:
+ data = file.readlines()
+ deps = get_pkg_deps(pkg_name)
+
+ for idx, line in enumerate(data):
+ split_line = line.decode().split(" =", 1)
+ if split_line[0] in deps and not split_line[1].startswith(' { registry'):
+ tmp = split_line[1].replace("workspace = true", "version = \"" + version + "\"")
+ tmp = tmp.replace("{", '').lstrip()
+ data[idx] = bytes(split_line[0] + ' = { registry = "kellnr", ' + tmp, 'utf-8')
+
+with open(cargo_toml, 'wb') as file:
+ file.writelines(data)
diff --git a/ci/docker-run.sh b/ci/docker-run.sh
index 427ee7b319e1c9..66d44b4458cd5c 100755
--- a/ci/docker-run.sh
+++ b/ci/docker-run.sh
@@ -94,6 +94,12 @@ if [[ -z "$SOLANA_DOCKER_RUN_NOSETUID" ]]; then
ARGS+=(--user "$(id -u):$(id -g)")
fi
+if [[ -n "$CRATE_PUBLISH_TEST" ]]; then
+ ARGS+=(
+ --network container:kellnr
+ )
+fi
+
if [[ -n $SOLANA_ALLOCATE_TTY ]]; then
# Colored output, progress bar and Ctrl-C:
# https://stackoverflow.com/a/41099052/10242004
diff --git a/ci/docker/Dockerfile b/ci/docker/Dockerfile
index 7d3fa3b8a0c1b4..514317b5ad72f7 100644
--- a/ci/docker/Dockerfile
+++ b/ci/docker/Dockerfile
@@ -82,7 +82,7 @@ RUN \
# uncomment once the dcou-parition related patch is upstreamed...
# cargo install cargo-hack && \
cargo install --git https://github.com/anza-xyz/cargo-hack.git --rev 5e59c3ec6c661c02601487c0d4b2a2649fe06c9f cargo-hack && \
- cargo install cargo-sort && \
+ cargo install cargo-sort@^2 && \
cargo install mdbook && \
cargo install mdbook-linkcheck && \
cargo install svgbob_cli && \
diff --git a/ci/env.sh b/ci/env.sh
index 953e880e399b28..1fc62a1bd786de 100644
--- a/ci/env.sh
+++ b/ci/env.sh
@@ -50,6 +50,9 @@ if [[ -n $CI ]]; then
else
export CI_TAG=$BUILDKITE_TAG
fi
+ if [[ -n $CRATE_PUBLISH_TEST ]]; then
+ export CRATE_PUBLISH_TEST=$CRATE_PUBLISH_TEST
+ fi
elif [[ -n $APPVEYOR ]]; then
export CI_BRANCH=$APPVEYOR_REPO_BRANCH
export CI_BUILD_ID=$APPVEYOR_BUILD_ID
diff --git a/ci/order-crates-for-publishing.py b/ci/order-crates-for-publishing.py
index 6bfda2b29df0d0..1480a4ed0e516d 100755
--- a/ci/order-crates-for-publishing.py
+++ b/ci/order-crates-for-publishing.py
@@ -10,7 +10,7 @@
import os
import json
import subprocess
-import sys;
+import sys
real_file = os.path.realpath(__file__)
ci_path = os.path.dirname(real_file)
@@ -82,7 +82,7 @@ def is_path_dev_dep(dependency):
)
def should_add(package, dependency, wrong_self_dev_dependencies):
- related_to_solana = dependency['name'].startswith('solana')
+ related_to_solana = dependency['name'].startswith(('solana','agave'))
self_dev_dep_with_dev_context_only_utils = is_self_dev_dep_with_dev_context_only_utils(
package, dependency, wrong_self_dev_dependencies
)
@@ -102,10 +102,10 @@ def get_packages():
wrong_self_dev_dependencies = list()
for pkg in metadata['packages']:
- manifest_path[pkg['name']] = pkg['manifest_path'];
+ manifest_path[pkg['name']] = pkg['manifest_path']
dependency_graph[pkg['name']] = [
x['name'] for x in pkg['dependencies'] if should_add(pkg, x, wrong_self_dev_dependencies)
- ];
+ ]
# Check for direct circular dependencies
circular_dependencies = set()
diff --git a/ci/publish-crate.sh b/ci/publish-crate.sh
index 5d7f3b1e1e1c50..3cb41ddff89be3 100755
--- a/ci/publish-crate.sh
+++ b/ci/publish-crate.sh
@@ -1,21 +1,60 @@
#!/usr/bin/env bash
-set -e
+
+# shellcheck disable=SC2317
+cleanup() {
+ ec=$?
+ docker container stop kellnr || true && docker container prune -f;
+ exit "$ec"
+}
+
+err_handler() {
+ ec=$?
+ echo "ERROR line $1: $BASH_COMMAND"
+ exit "$ec"
+}
+
+trap cleanup EXIT
+trap err_handler ERR SIGINT
+
+set -Ee
+
cd "$(dirname "$0")/.."
source ci/semver_bash/semver.sh
source ci/rust-version.sh stable
+DRY_RUN=false
+if [[ $1 = --dry-run ]]; then
+ DRY_RUN=true
+ export CRATE_PUBLISH_TEST=true
+ shift
+fi
+
+if $DRY_RUN; then
+ cp ci/cargo/config.toml .cargo/config.toml
+fi
+
# shellcheck disable=SC2086
is_crate_version_uploaded() {
name=$1
version=$2
- curl https://crates.io/api/v1/crates/${name}/${version} | \
- python3 -c "import sys,json; print('version' in json.load(sys.stdin));"
+ if $DRY_RUN; then
+ curl http://127.0.0.1:8000/api/v1/crates/${name}/crate_versions | \
+ python3 -c "import sys,json; print(len(json.load(sys.stdin)['versions']) > 0);"
+ else
+ curl https://crates.io/api/v1/crates/${name}/${version} | \
+ python3 -c "import sys,json; print('version' in json.load(sys.stdin));"
+ fi
}
# Only package/publish if this is a tagged release
[[ -n $CI_TAG ]] || {
+if $DRY_RUN; then
+ CI_TAG=$(grep '^version = "' Cargo.toml | cut -d "=" -f2 | xargs)
+ CRATES_IO_TOKEN="test"
+else
echo CI_TAG unset, skipped
exit 0
+fi
}
semverParseInto "$CI_TAG" MAJOR MINOR PATCH SPECIAL
@@ -37,10 +76,14 @@ done
Cargo_tomls=$(ci/order-crates-for-publishing.py)
+if $DRY_RUN; then
+ docker run --name kellnr -d ghcr.io/kellnr/kellnr:5
+fi
+
for Cargo_toml in $Cargo_tomls; do
echo "--- $Cargo_toml"
- # check the version which doesn't inherit from worksapce
+ # check the version which doesn't inherit from workspace
if ! grep -q "^version = { workspace = true }$" "$Cargo_toml"; then
echo "Warn: $Cargo_toml doesn't use the inherited version"
grep -q "^version = \"$expectedCrateVersion\"$" "$Cargo_toml" || {
@@ -62,10 +105,16 @@ for Cargo_toml in $Cargo_tomls; do
fi
(
- set -x
-
crate=$(dirname "$Cargo_toml")
- cargoCommand="cargo publish --token $CRATES_IO_TOKEN"
+ if $DRY_RUN; then
+ ci/change-crate-deps.py "$Cargo_toml" "$crate_name"
+
+ # token is a default value from the kellnr image https://kellnr.io/documentation#config-values
+ # registry value is defined in docker-run.sh script
+ cargoCommand="cargo publish --registry kellnr --token Zy9HhJ02RJmg0GCrgLfaCVfU6IwDfhXD --allow-dirty"
+ else
+ cargoCommand="cargo publish --token $CRATES_IO_TOKEN"
+ fi
numRetries=10
for ((i = 1; i <= numRetries; i++)); do
diff --git a/clap-utils/Cargo.toml b/clap-utils/Cargo.toml
index da9298ca776777..a0e9f610816e4a 100644
--- a/clap-utils/Cargo.toml
+++ b/clap-utils/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_clap_utils"
+
[dependencies]
chrono = { workspace = true, features = ["default"] }
clap = "2.33.0"
@@ -37,9 +43,3 @@ assert_matches = { workspace = true }
solana-pubkey = { workspace = true, features = ["rand"] }
solana-system-interface = { workspace = true, features = ["bincode"] }
tempfile = { workspace = true }
-
-[lib]
-name = "solana_clap_utils"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/clap-v3-utils/Cargo.toml b/clap-v3-utils/Cargo.toml
index 1a2d15ce5986d3..4dce300b4f38f2 100644
--- a/clap-v3-utils/Cargo.toml
+++ b/clap-v3-utils/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_clap_v3_utils"
+
[dependencies]
chrono = { workspace = true, features = ["default"] }
clap = { version = "3.2.23", features = ["cargo"] }
@@ -40,9 +46,3 @@ assert_matches = { workspace = true }
solana-pubkey = { workspace = true, features = ["rand"] }
solana-system-interface = { workspace = true, features = ["bincode"] }
tempfile = { workspace = true }
-
-[lib]
-name = "solana_clap_v3_utils"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/cli-config/Cargo.toml b/cli-config/Cargo.toml
index 3a67a6ac35f045..dd322b07b68148 100644
--- a/cli-config/Cargo.toml
+++ b/cli-config/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
dirs-next = { workspace = true }
serde = { workspace = true }
@@ -20,6 +23,3 @@ url = { workspace = true }
[dev-dependencies]
anyhow = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/cli-output/Cargo.toml b/cli-output/Cargo.toml
index 3cc8cd9bc270eb..8af951f23c92b9 100644
--- a/cli-output/Cargo.toml
+++ b/cli-output/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
Inflector = { workspace = true }
agave-reserved-account-keys = { workspace = true }
@@ -33,11 +36,11 @@ solana-hash = { workspace = true }
solana-message = { workspace = true }
solana-native-token = { workspace = true }
solana-packet = { workspace = true }
-solana-program = { workspace = true }
solana-pubkey = { workspace = true }
solana-rpc-client-api = { workspace = true }
solana-sdk-ids = { workspace = true }
solana-signature = { workspace = true }
+solana-stake-interface = { workspace = true }
solana-system-interface = { workspace = true }
solana-sysvar = { workspace = true }
solana-transaction = { workspace = true, features = ["verify"] }
@@ -51,6 +54,3 @@ ed25519-dalek = { workspace = true }
solana-keypair = { workspace = true }
solana-signer = { workspace = true }
solana-transaction-context = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/cli-output/src/cli_output.rs b/cli-output/src/cli_output.rs
index a54baa18aaa521..4aad5021051af7 100644
--- a/cli-output/src/cli_output.rs
+++ b/cli-output/src/cli_output.rs
@@ -26,13 +26,13 @@ use {
solana_epoch_info::EpochInfo,
solana_hash::Hash,
solana_native_token::lamports_to_sol,
- solana_program::stake::state::{Authorized, Lockup},
solana_pubkey::Pubkey,
solana_rpc_client_api::response::{
RpcAccountBalance, RpcContactInfo, RpcInflationGovernor, RpcInflationRate, RpcKeyedAccount,
RpcSupply, RpcVoteAccountInfo,
},
solana_signature::Signature,
+ solana_stake_interface::state::{Authorized, Lockup},
solana_sysvar::stake_history::StakeHistoryEntry,
solana_transaction::{versioned::VersionedTransaction, Transaction},
solana_transaction_error::TransactionError,
diff --git a/cli-output/src/display.rs b/cli-output/src/display.rs
index f0d64c3087dcab..5613746c0fc1b4 100644
--- a/cli-output/src/display.rs
+++ b/cli-output/src/display.rs
@@ -11,9 +11,9 @@ use {
solana_hash::Hash,
solana_message::{compiled_instruction::CompiledInstruction, v0::MessageAddressTableLookup},
solana_native_token::lamports_to_sol,
- solana_program::stake,
solana_pubkey::Pubkey,
solana_signature::Signature,
+ solana_stake_interface as stake,
solana_transaction::versioned::{TransactionVersion, VersionedTransaction},
solana_transaction_error::TransactionError,
solana_transaction_status::{
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 6a980ac4173817..dfa9fe70e05675 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[[bin]]
+name = "solana"
+path = "src/main.rs"
+
[dependencies]
agave-feature-set = { workspace = true }
bincode = { workspace = true }
@@ -31,6 +38,7 @@ serde_derive = { workspace = true }
serde_json = { workspace = true }
solana-account = "=2.2.1"
solana-account-decoder = { workspace = true }
+solana-address-lookup-table-interface = { workspace = true }
solana-borsh = "=2.2.1"
solana-bpf-loader-program = { workspace = true }
solana-clap-utils = { workspace = true }
@@ -41,6 +49,7 @@ solana-clock = "=2.2.2"
solana-cluster-type = "=2.2.1"
solana-commitment-config = "=2.2.1"
solana-compute-budget-interface = { version = "=2.2.2", features = ["borsh"] }
+solana-config-interface = "=1.0.0"
solana-config-program-client = { workspace = true, features = ["serde"] }
solana-connection-cache = { workspace = true }
solana-decode-error = "=2.2.1"
@@ -48,20 +57,19 @@ solana-epoch-schedule = "=2.2.1"
solana-feature-gate-client = "=0.0.2"
solana-feature-gate-interface = "=2.2.2"
solana-fee-calculator = "=2.2.1"
-solana-fee-structure = "=2.2.1"
+solana-fee-structure = "=2.3.0"
solana-hash = "=2.3.0"
-solana-instruction = "=2.2.1"
+solana-instruction = "=2.3.0"
solana-keypair = "=2.2.1"
solana-loader-v3-interface = { version = "=5.0.0", features = ["bincode"] }
solana-loader-v4-interface = "=2.2.1"
solana-loader-v4-program = { workspace = true }
solana-logger = "=2.3.1"
-solana-message = "=2.3.0"
+solana-message = "=2.4.0"
solana-native-token = "=2.2.2"
solana-nonce = "=2.2.1"
solana-offchain-message = { version = "=2.2.1", features = ["verify"] }
solana-packet = "=2.2.1"
-solana-program = { version = "=2.2.1", default-features = false }
solana-program-runtime = { workspace = true }
solana-pubkey = { version = "=2.4.0", default-features = false }
solana-pubsub-client = { workspace = true }
@@ -103,10 +111,3 @@ solana-streamer = { workspace = true }
solana-test-validator = { workspace = true }
tempfile = { workspace = true }
test-case = { workspace = true }
-
-[[bin]]
-name = "solana"
-path = "src/main.rs"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/cli/src/address_lookup_table.rs b/cli/src/address_lookup_table.rs
index 7dc861d13636f1..cb5f1a45b4c0aa 100644
--- a/cli/src/address_lookup_table.rs
+++ b/cli/src/address_lookup_table.rs
@@ -2,19 +2,19 @@ use {
crate::cli::{CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult},
clap::{App, AppSettings, Arg, ArgMatches, SubCommand},
solana_account::from_account,
- solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*},
- solana_cli_output::{CliAddressLookupTable, CliAddressLookupTableCreated, CliSignature},
- solana_clock::Clock,
- solana_commitment_config::CommitmentConfig,
- solana_message::Message,
- solana_program::address_lookup_table::{
- self,
+ solana_address_lookup_table_interface::{
+ self as address_lookup_table,
instruction::{
close_lookup_table, create_lookup_table, deactivate_lookup_table, extend_lookup_table,
freeze_lookup_table,
},
state::AddressLookupTable,
},
+ solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*},
+ solana_cli_output::{CliAddressLookupTable, CliAddressLookupTableCreated, CliSignature},
+ solana_clock::Clock,
+ solana_commitment_config::CommitmentConfig,
+ solana_message::Message,
solana_pubkey::Pubkey,
solana_remote_wallet::remote_wallet::RemoteWalletManager,
solana_rpc_client::rpc_client::RpcClient,
diff --git a/cli/src/cli.rs b/cli/src/cli.rs
index a7d5d5cbf8074f..5a8791a668db84 100644
--- a/cli/src/cli.rs
+++ b/cli/src/cli.rs
@@ -20,7 +20,6 @@ use {
solana_instruction::error::InstructionError,
solana_keypair::{read_keypair_file, Keypair},
solana_offchain_message::OffchainMessage,
- solana_program::stake::{instruction::LockupArgs, state::Lockup},
solana_pubkey::Pubkey,
solana_remote_wallet::remote_wallet::RemoteWalletManager,
solana_rpc_client::rpc_client::RpcClient,
@@ -31,6 +30,7 @@ use {
solana_rpc_client_nonce_utils::blockhash_query::BlockhashQuery,
solana_signature::Signature,
solana_signer::{Signer, SignerError},
+ solana_stake_interface::{instruction::LockupArgs, state::Lockup},
solana_tps_client::{utils::create_connection_cache, TpsClient},
solana_tpu_client::tpu_client::{
TpuClient, TpuClientConfig, DEFAULT_TPU_CONNECTION_POOL_SIZE, DEFAULT_TPU_ENABLE_UDP,
diff --git a/cli/src/cluster_query.rs b/cli/src/cluster_query.rs
index c0275d4b05d3d7..b74868ce8867c1 100644
--- a/cli/src/cluster_query.rs
+++ b/cli/src/cluster_query.rs
@@ -33,7 +33,6 @@ use {
solana_message::Message,
solana_native_token::lamports_to_sol,
solana_nonce::state::State as NonceState,
- solana_program::stake::{self, state::StakeStateV2},
solana_pubkey::Pubkey,
solana_pubsub_client::pubsub_client::PubsubClient,
solana_remote_wallet::remote_wallet::RemoteWalletManager,
@@ -53,6 +52,7 @@ use {
solana_sdk_ids::sysvar::{self, stake_history},
solana_signature::Signature,
solana_slot_history::{self as slot_history, SlotHistory},
+ solana_stake_interface::{self as stake, state::StakeStateV2},
solana_system_interface::{instruction as system_instruction, MAX_PERMITTED_DATA_LENGTH},
solana_tps_client::TpsClient,
solana_transaction::Transaction,
diff --git a/cli/src/stake.rs b/cli/src/stake.rs
index bc5300f6345e55..a9667033ca7b7b 100644
--- a/cli/src/stake.rs
+++ b/cli/src/stake.rs
@@ -37,12 +37,6 @@ use {
solana_epoch_schedule::EpochSchedule,
solana_message::Message,
solana_native_token::Sol,
- solana_program::stake::{
- self,
- instruction::{self as stake_instruction, LockupArgs, StakeError},
- state::{Authorized, Lockup, Meta, StakeActivationStatus, StakeAuthorize, StakeStateV2},
- tools::{acceptable_reference_epoch_credits, eligible_for_deactivate_delinquent},
- },
solana_pubkey::Pubkey,
solana_remote_wallet::remote_wallet::RemoteWalletManager,
solana_rpc_client::rpc_client::RpcClient,
@@ -56,6 +50,13 @@ use {
system_program,
sysvar::{clock, stake_history},
},
+ solana_stake_interface::{
+ self as stake,
+ error::StakeError,
+ instruction::{self as stake_instruction, LockupArgs},
+ state::{Authorized, Lockup, Meta, StakeActivationStatus, StakeAuthorize, StakeStateV2},
+ tools::{acceptable_reference_epoch_credits, eligible_for_deactivate_delinquent},
+ },
solana_system_interface::{error::SystemError, instruction as system_instruction},
solana_sysvar::stake_history::StakeHistory,
solana_transaction::Transaction,
diff --git a/cli/src/validator_info.rs b/cli/src/validator_info.rs
index 950710450d6f35..9920e0b2431b69 100644
--- a/cli/src/validator_info.rs
+++ b/cli/src/validator_info.rs
@@ -10,7 +10,7 @@ use {
serde_json::{Map, Value},
solana_account::Account,
solana_account_decoder::validator_info::{
- self, ValidatorInfo, MAX_LONG_FIELD_LENGTH, MAX_SHORT_FIELD_LENGTH,
+ self, ValidatorInfo, MAX_LONG_FIELD_LENGTH, MAX_SHORT_FIELD_LENGTH, MAX_VALIDATOR_INFO,
},
solana_clap_utils::{
compute_budget::{compute_unit_price_arg, ComputeUnitLimit, COMPUTE_UNIT_PRICE_ARG},
@@ -20,11 +20,8 @@ use {
keypair::DefaultSigner,
},
solana_cli_output::{CliValidatorInfo, CliValidatorInfoVec},
- solana_config_program_client::{
- get_config_data,
- instructions_bincode::{self as config_instruction, ConfigState},
- ConfigKeys,
- },
+ solana_config_interface::instruction::{self as config_instruction},
+ solana_config_program_client::{get_config_data, ConfigKeys},
solana_keypair::Keypair,
solana_message::Message,
solana_pubkey::Pubkey,
@@ -48,7 +45,7 @@ pub fn check_details_length(string: String) -> Result<(), String> {
pub fn check_total_length(info: &ValidatorInfo) -> Result<(), String> {
let size = serialized_size(&info).unwrap();
- let limit = ValidatorInfo::max_space();
+ let limit = MAX_VALIDATOR_INFO;
if size > limit {
Err(format!(
@@ -337,7 +334,7 @@ pub fn process_set_validator_info(
(validator_info::id(), false),
(config.signers[0].pubkey(), true),
];
- let data_len = ValidatorInfo::max_space()
+ let data_len = MAX_VALIDATOR_INFO
.checked_add(serialized_size(&ConfigKeys { keys: keys.clone() }).unwrap())
.expect("ValidatorInfo and two keys fit into a u64");
let lamports = rpc_client.get_minimum_balance_for_rent_exemption(data_len as usize)?;
@@ -360,16 +357,18 @@ pub fn process_set_validator_info(
"Publishing info for Validator {:?}",
config.signers[0].pubkey()
);
- let mut instructions = config_instruction::create_account::(
- &config.signers[0].pubkey(),
- &info_pubkey,
- lamports,
- keys.clone(),
- )
- .with_compute_unit_config(&ComputeUnitConfig {
- compute_unit_price,
- compute_unit_limit,
- });
+ let mut instructions =
+ config_instruction::create_account_with_max_config_space::(
+ &config.signers[0].pubkey(),
+ &info_pubkey,
+ lamports,
+ MAX_VALIDATOR_INFO,
+ keys.clone(),
+ )
+ .with_compute_unit_config(&ComputeUnitConfig {
+ compute_unit_price,
+ compute_unit_limit,
+ });
instructions.extend_from_slice(&[config_instruction::store(
&info_pubkey,
true,
@@ -661,7 +660,7 @@ mod tests {
assert_eq!(
serialized_size(&validator_info).unwrap(),
- ValidatorInfo::max_space()
+ MAX_VALIDATOR_INFO
);
}
}
diff --git a/client-test/Cargo.toml b/client-test/Cargo.toml
index 3368bb6b06ae99..f1551e8e9a95d0 100644
--- a/client-test/Cargo.toml
+++ b/client-test/Cargo.toml
@@ -10,6 +10,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
futures-util = { workspace = true }
serde_json = { workspace = true }
@@ -46,6 +49,3 @@ solana-logger = { workspace = true }
solana-net-utils = { workspace = true }
solana-rpc = { workspace = true, features = ["dev-context-only-utils"] }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/client-test/tests/client.rs b/client-test/tests/client.rs
index 6781f2de7bb7f2..8d8e938abc8405 100644
--- a/client-test/tests/client.rs
+++ b/client-test/tests/client.rs
@@ -135,11 +135,9 @@ fn test_account_subscription() {
bank_forks.write().unwrap().insert(bank1);
let bob = Keypair::new();
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks),
@@ -253,12 +251,10 @@ fn test_block_subscription() {
max_complete_transaction_status_slot,
);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
// setup RpcSubscriptions && PubSubService
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests_with_blockstore(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
blockstore.clone(),
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
@@ -341,11 +337,9 @@ fn test_program_subscription() {
bank_forks.write().unwrap().insert(bank1);
let bob = Keypair::new();
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks),
@@ -427,11 +421,9 @@ fn test_root_subscription() {
let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1);
bank_forks.write().unwrap().insert(bank1);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks),
@@ -478,11 +470,9 @@ fn test_slot_subscription() {
let optimistically_confirmed_bank =
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks,
Arc::new(RwLock::new(BlockCommitmentCache::default())),
optimistically_confirmed_bank,
@@ -554,11 +544,9 @@ async fn test_slot_subscription_async() {
let optimistically_confirmed_bank =
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks,
Arc::new(RwLock::new(BlockCommitmentCache::default())),
optimistically_confirmed_bank,
diff --git a/client/Cargo.toml b/client/Cargo.toml
index 986a926fd87761..b9bf4f9604e658 100644
--- a/client/Cargo.toml
+++ b/client/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
async-trait = { workspace = true }
bincode = { workspace = true }
@@ -52,6 +55,3 @@ tokio = { workspace = true, features = ["full"] }
[dev-dependencies]
crossbeam-channel = { workspace = true }
solana-net-utils = { workspace = true, features = ["dev-context-only-utils"] }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/compute-budget-instruction/Cargo.toml b/compute-budget-instruction/Cargo.toml
index 779418adb2ec0e..8971b9b619c6bf 100644
--- a/compute-budget-instruction/Cargo.toml
+++ b/compute-budget-instruction/Cargo.toml
@@ -9,6 +9,16 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_compute_budget_instruction"
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
agave-feature-set = { workspace = true }
log = { workspace = true }
@@ -24,10 +34,6 @@ solana-svm-transaction = { workspace = true }
solana-transaction-error = { workspace = true }
thiserror = { workspace = true }
-[lib]
-crate-type = ["lib"]
-name = "solana_compute_budget_instruction"
-
[dev-dependencies]
bincode = { workspace = true }
criterion = { workspace = true }
@@ -36,17 +42,11 @@ solana-builtins-default-costs = { workspace = true, features = ["dev-context-onl
solana-hash = { workspace = true }
solana-keypair = { workspace = true }
solana-message = { workspace = true }
-solana-program = { workspace = true }
solana-signer = { workspace = true }
+solana-stake-interface = { workspace = true }
solana-system-interface = { workspace = true }
solana-transaction = { workspace = true, features = ["blake3"] }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = []
-
[[bench]]
name = "process_compute_budget_instructions"
harness = false
diff --git a/compute-budget-instruction/src/compute_budget_instruction_details.rs b/compute-budget-instruction/src/compute_budget_instruction_details.rs
index 23a0b4bd234759..c25847bd238f8a 100644
--- a/compute-budget-instruction/src/compute_budget_instruction_details.rs
+++ b/compute-budget-instruction/src/compute_budget_instruction_details.rs
@@ -516,7 +516,7 @@ mod test {
fn test_builtin_program_migration() {
let tx = build_sanitized_transaction(&[
Instruction::new_with_bincode(Pubkey::new_unique(), &(), vec![]),
- solana_program::stake::instruction::delegate_stake(
+ solana_stake_interface::instruction::delegate_stake(
&Pubkey::new_unique(),
&Pubkey::new_unique(),
&Pubkey::new_unique(),
diff --git a/compute-budget/Cargo.toml b/compute-budget/Cargo.toml
index 2a9a1b3e9d41df..d5a93b4958b9e9 100644
--- a/compute-budget/Cargo.toml
+++ b/compute-budget/Cargo.toml
@@ -9,6 +9,10 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[features]
+dev-context-only-utils = ["dep:qualifier_attr"]
+frozen-abi = ["dep:solana-frozen-abi", "solana-fee-structure/frozen-abi"]
+
[dependencies]
qualifier_attr = { workspace = true, optional = true }
solana-fee-structure = { workspace = true }
@@ -17,9 +21,5 @@ solana-frozen-abi = { workspace = true, optional = true, features = [
] }
solana-program-runtime = { workspace = true }
-[features]
-dev-context-only-utils = ["dep:qualifier_attr"]
-frozen-abi = ["dep:solana-frozen-abi", "solana-fee-structure/frozen-abi"]
-
[lints]
workspace = true
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 40d48e24084626..85a0b12fcee584 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -10,8 +10,35 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
-[badges]
-codecov = { repository = "solana-labs/solana", branch = "master", service = "github" }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = [
+ "solana-perf/dev-context-only-utils",
+ "solana-runtime/dev-context-only-utils",
+ "solana-streamer/dev-context-only-utils",
+]
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-accounts-db/frozen-abi",
+ "solana-bloom/frozen-abi",
+ "solana-compute-budget/frozen-abi",
+ "solana-cost-model/frozen-abi",
+ "solana-frozen-abi/frozen-abi",
+ "solana-gossip/frozen-abi",
+ "solana-ledger/frozen-abi",
+ "solana-packet/frozen-abi",
+ "solana-perf/frozen-abi",
+ "solana-program-runtime/frozen-abi",
+ "solana-runtime/frozen-abi",
+ "solana-short-vec/frozen-abi",
+ "solana-signature/frozen-abi",
+ "solana-svm/frozen-abi",
+ "solana-vote/frozen-abi",
+ "solana-vote-program/frozen-abi",
+]
[dependencies]
agave-banking-stage-ingress-types = { workspace = true }
@@ -30,6 +57,7 @@ chrono = { workspace = true, features = ["default", "serde"] }
conditional-mod = { workspace = true }
crossbeam-channel = { workspace = true }
dashmap = { workspace = true, features = ["rayon", "raw-api"] }
+derive_more = { workspace = true }
etcd-client = { workspace = true, features = ["tls"] }
futures = { workspace = true }
histogram = { workspace = true }
@@ -135,7 +163,7 @@ solana-vortexor-receiver = { workspace = true }
solana-vote = { workspace = true }
solana-vote-program = { workspace = true }
solana-wen-restart = { workspace = true }
-static_assertions ={ workspace = true }
+static_assertions = { workspace = true }
strum = { workspace = true, features = ["derive"] }
strum_macros = { workspace = true }
sys-info = { workspace = true }
@@ -145,12 +173,19 @@ tokio = { workspace = true, features = ["full"] }
tokio-util = { workspace = true }
trees = { workspace = true }
+[target.'cfg(not(any(target_env = "msvc", target_os = "freebsd")))'.dependencies]
+jemallocator = { workspace = true }
+
+[target."cfg(unix)".dependencies]
+sysctl = { workspace = true }
+
[dev-dependencies]
agave-reserved-account-keys = { workspace = true }
criterion = { workspace = true }
fs_extra = { workspace = true }
serde_json = { workspace = true }
serial_test = { workspace = true }
+solana-account = { workspace = true, features = ["dev-context-only-utils"] }
# See order-crates-for-publishing.py for using this unusual `path = "."`
solana-bpf-loader-program = { workspace = true }
solana-compute-budget-interface = { workspace = true }
@@ -164,7 +199,6 @@ solana-net-utils = { workspace = true, features = ["dev-context-only-utils"] }
solana-poh = { workspace = true, features = ["dev-context-only-utils"] }
solana-program-runtime = { workspace = true, features = ["metrics"] }
solana-rpc = { workspace = true, features = ["dev-context-only-utils"] }
-solana-sdk = { workspace = true, features = ["full", "dev-context-only-utils"] }
solana-stake-program = { workspace = true }
solana-system-program = { workspace = true }
solana-unified-scheduler-logic = { workspace = true }
@@ -176,36 +210,8 @@ spl-memo = { workspace = true, features = ["no-entrypoint"] }
static_assertions = { workspace = true }
test-case = { workspace = true }
-[target."cfg(unix)".dependencies]
-sysctl = { workspace = true }
-
-[target.'cfg(not(any(target_env = "msvc", target_os = "freebsd")))'.dependencies]
-jemallocator = { workspace = true }
-
-[features]
-dev-context-only-utils = [
- "solana-perf/dev-context-only-utils",
- "solana-runtime/dev-context-only-utils",
- "solana-streamer/dev-context-only-utils",
-]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-accounts-db/frozen-abi",
- "solana-bloom/frozen-abi",
- "solana-compute-budget/frozen-abi",
- "solana-cost-model/frozen-abi",
- "solana-gossip/frozen-abi",
- "solana-ledger/frozen-abi",
- "solana-perf/frozen-abi",
- "solana-program-runtime/frozen-abi",
- "solana-runtime/frozen-abi",
- "solana-sdk/frozen-abi",
- "solana-short-vec/frozen-abi",
- "solana-svm/frozen-abi",
- "solana-vote/frozen-abi",
- "solana-vote-program/frozen-abi",
-]
+[badges]
+codecov = { repository = "solana-labs/solana", branch = "master", service = "github" }
[[bench]]
name = "banking_stage"
@@ -224,8 +230,5 @@ harness = false
name = "scheduler"
harness = false
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
[lints]
workspace = true
diff --git a/core/src/banking_stage/consume_worker.rs b/core/src/banking_stage/consume_worker.rs
index 461f644e6edd1d..575d0ccd9b30b5 100644
--- a/core/src/banking_stage/consume_worker.rs
+++ b/core/src/banking_stage/consume_worker.rs
@@ -768,6 +768,7 @@ mod tests {
thread::JoinHandle,
},
tempfile::TempDir,
+ test_case::test_case,
};
// Helper struct to create tests that hold channels, files, etc.
@@ -787,7 +788,9 @@ mod tests {
consumed_receiver: Receiver>>,
}
- fn setup_test_frame() -> (
+ fn setup_test_frame(
+ relax_intrabatch_account_locks: bool,
+ ) -> (
TestFrame,
ConsumeWorker>,
) {
@@ -798,11 +801,15 @@ mod tests {
} = create_slow_genesis_config(10_000);
let (bank, bank_forks) = Bank::new_no_wallclock_throttle_for_tests(&genesis_config);
// Warp to next epoch for MaxAge tests.
- let bank = Arc::new(Bank::new_from_parent(
+ let mut bank = Bank::new_from_parent(
bank.clone(),
&Pubkey::new_unique(),
bank.get_epoch_info().slots_in_epoch,
- ));
+ );
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
+ let bank = Arc::new(bank);
let ledger_path = get_tmp_ledger_path_auto_delete!();
let blockstore = Blockstore::open(ledger_path.path())
@@ -861,7 +868,7 @@ mod tests {
#[test]
fn test_worker_consume_no_bank() {
- let (test_frame, worker) = setup_test_frame();
+ let (test_frame, worker) = setup_test_frame(true);
let TestFrame {
mint_keypair,
genesis_config,
@@ -905,7 +912,7 @@ mod tests {
#[test]
fn test_worker_consume_simple() {
- let (test_frame, worker) = setup_test_frame();
+ let (test_frame, worker) = setup_test_frame(true);
let TestFrame {
mint_keypair,
genesis_config,
@@ -952,9 +959,10 @@ mod tests {
let _ = worker_thread.join().unwrap();
}
- #[test]
- fn test_worker_consume_self_conflicting() {
- let (test_frame, worker) = setup_test_frame();
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_worker_consume_self_conflicting(relax_intrabatch_account_locks: bool) {
+ let (test_frame, worker) = setup_test_frame(relax_intrabatch_account_locks);
let TestFrame {
mint_keypair,
genesis_config,
@@ -998,7 +1006,16 @@ mod tests {
assert_eq!(consumed.work.batch_id, bid);
assert_eq!(consumed.work.ids, vec![id1, id2]);
assert_eq!(consumed.work.max_ages, vec![max_age, max_age]);
- assert_eq!(consumed.retryable_indexes, vec![1]); // id2 is retryable since lock conflict
+
+ // id2 succeeds with simd83, or is retryable due to lock conflict without simd83
+ assert_eq!(
+ consumed.retryable_indexes,
+ if relax_intrabatch_account_locks {
+ vec![]
+ } else {
+ vec![1]
+ }
+ );
drop(test_frame);
let _ = worker_thread.join().unwrap();
@@ -1006,7 +1023,7 @@ mod tests {
#[test]
fn test_worker_consume_multiple_messages() {
- let (test_frame, worker) = setup_test_frame();
+ let (test_frame, worker) = setup_test_frame(true);
let TestFrame {
mint_keypair,
genesis_config,
@@ -1081,7 +1098,7 @@ mod tests {
#[test]
fn test_worker_ttl() {
- let (test_frame, worker) = setup_test_frame();
+ let (test_frame, worker) = setup_test_frame(true);
let TestFrame {
mint_keypair,
genesis_config,
diff --git a/core/src/banking_stage/consumer.rs b/core/src/banking_stage/consumer.rs
index d466ac47b7e09a..fd66ac995c8e07 100644
--- a/core/src/banking_stage/consumer.rs
+++ b/core/src/banking_stage/consumer.rs
@@ -531,6 +531,7 @@ mod tests {
thread::{Builder, JoinHandle},
time::Duration,
},
+ test_case::test_case,
};
fn execute_transactions_with_dummy_poh_service(
@@ -832,8 +833,8 @@ mod tests {
if let Ok(record) = record {
let record_response = poh_recorder.write().unwrap().record(
record.slot,
- record.mixin,
- record.transactions,
+ record.mixins,
+ record.transaction_batches,
);
poh_recorder.write().unwrap().tick();
if record.sender.send(record_response).is_err() {
@@ -1007,8 +1008,11 @@ mod tests {
let _ = poh_simulator.join();
}
- #[test]
- fn test_bank_process_and_record_transactions_cost_tracker() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_bank_process_and_record_transactions_cost_tracker(
+ relax_intrabatch_account_locks: bool,
+ ) {
solana_logger::setup();
let GenesisConfigInfo {
genesis_config,
@@ -1016,6 +1020,9 @@ mod tests {
..
} = create_slow_genesis_config(10_000);
let mut bank = Bank::new_for_tests(&genesis_config);
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
bank.ns_per_slot = u128::MAX;
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
let pubkey = solana_pubkey::new_rand();
@@ -1098,6 +1105,14 @@ mod tests {
system_transaction::transfer(&mint_keypair, &pubkey, 2, genesis_config.hash()),
]);
+ let conflicting_transaction = sanitize_transactions(vec![system_transaction::transfer(
+ &Keypair::new(),
+ &pubkey,
+ 1,
+ genesis_config.hash(),
+ )]);
+ bank.try_lock_accounts(&conflicting_transaction);
+
let process_transactions_batch_output =
consumer.process_and_record_transactions(&bank, &transactions);
@@ -1162,22 +1177,46 @@ mod tests {
let _ = poh_simulator.join();
}
- #[test]
- fn test_bank_process_and_record_transactions_account_in_use() {
+ #[test_case(false, false; "old::locked")]
+ #[test_case(false, true; "old::duplicate")]
+ #[test_case(true, false; "simd83::locked")]
+ #[test_case(true, true; "simd83::duplicate")]
+ fn test_bank_process_and_record_transactions_account_in_use(
+ relax_intrabatch_account_locks: bool,
+ use_duplicate_transaction: bool,
+ ) {
solana_logger::setup();
let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_slow_genesis_config(10_000);
- let (bank, _bank_forks) = Bank::new_no_wallclock_throttle_for_tests(&genesis_config);
+ let mut bank = Bank::new_for_tests(&genesis_config);
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
+ bank.ns_per_slot = u128::MAX;
+ let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
let pubkey = solana_pubkey::new_rand();
let pubkey1 = solana_pubkey::new_rand();
let transactions = sanitize_transactions(vec![
system_transaction::transfer(&mint_keypair, &pubkey, 1, genesis_config.hash()),
- system_transaction::transfer(&mint_keypair, &pubkey1, 1, genesis_config.hash()),
+ system_transaction::transfer(
+ &mint_keypair,
+ if use_duplicate_transaction {
+ &pubkey
+ } else {
+ &pubkey1
+ },
+ 1,
+ genesis_config.hash(),
+ ),
]);
+ assert_eq!(
+ transactions[0].message_hash() == transactions[1].message_hash(),
+ use_duplicate_transaction
+ );
let ledger_path = get_tmp_ledger_path_auto_delete!();
let blockstore = Blockstore::open(ledger_path.path())
@@ -1212,6 +1251,20 @@ mod tests {
);
let consumer = Consumer::new(committer, recorder, QosService::new(1), None);
+ // with simd83 and no duplicate, we take a cross-batch lock on an account to create a conflict
+ // with a duplicate transaction and simd83 it comes from message hash equality in the batch
+ // without simd83 the conflict comes from locks in batch
+ if relax_intrabatch_account_locks && !use_duplicate_transaction {
+ let conflicting_transaction =
+ sanitize_transactions(vec![system_transaction::transfer(
+ &Keypair::new(),
+ &pubkey1,
+ 1,
+ genesis_config.hash(),
+ )]);
+ bank.try_lock_accounts(&conflicting_transaction);
+ }
+
let process_transactions_batch_output =
consumer.process_and_record_transactions(&bank, &transactions);
@@ -1237,8 +1290,14 @@ mod tests {
processed_with_successful_result_count: 1,
}
);
- assert_eq!(retryable_transaction_indexes, vec![1]);
assert!(commit_transactions_result.is_ok());
+
+ // with simd3, duplicate transactions are not retryable
+ if relax_intrabatch_account_locks && use_duplicate_transaction {
+ assert_eq!(retryable_transaction_indexes, Vec::::new());
+ } else {
+ assert_eq!(retryable_transaction_indexes, vec![1]);
+ }
}
#[test]
@@ -1297,30 +1356,48 @@ mod tests {
);
}
- #[test]
- fn test_process_transactions_account_in_use() {
+ #[test_case(false, false; "old::locked")]
+ #[test_case(false, true; "old::duplicate")]
+ #[test_case(true, false; "simd83::locked")]
+ #[test_case(true, true; "simd83::duplicate")]
+ fn test_process_transactions_account_in_use(
+ relax_intrabatch_account_locks: bool,
+ use_duplicate_transaction: bool,
+ ) {
solana_logger::setup();
let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_slow_genesis_config(10_000);
- let (bank, _bank_forks) = Bank::new_no_wallclock_throttle_for_tests(&genesis_config);
+ let mut bank = Bank::new_for_tests(&genesis_config);
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
+ bank.ns_per_slot = u128::MAX;
+ let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
// set cost tracker limits to MAX so it will not filter out TXs
bank.write_cost_tracker()
.unwrap()
.set_limits(u64::MAX, u64::MAX, u64::MAX);
- // Make all repetitive transactions that conflict on the `mint_keypair`, so only 1 should be executed
- let transactions = vec![
- system_transaction::transfer(
+ let mut transactions = vec![];
+ let destination = Pubkey::new_unique();
+ let mut amount = 1;
+
+ // Make distinct, or identical, transactions that conflict on the `mint_keypair`
+ for _ in 0..TARGET_NUM_TRANSACTIONS_PER_BATCH {
+ transactions.push(system_transaction::transfer(
&mint_keypair,
- &Pubkey::new_unique(),
- 1,
- genesis_config.hash()
- );
- TARGET_NUM_TRANSACTIONS_PER_BATCH
- ];
+ &destination,
+ amount,
+ genesis_config.hash(),
+ ));
+
+ if !use_duplicate_transaction {
+ amount += 1;
+ }
+ }
let transactions_len = transactions.len();
let ProcessTransactionBatchOutput {
@@ -1328,7 +1405,14 @@ mod tests {
..
} = execute_transactions_with_dummy_poh_service(bank, transactions);
- // All the transactions should have been replayed, but only 2 committed (first and last)
+ // If SIMD-83 is enabled *and* the transactions are distinct, all are executed.
+ // In the three other cases, only one is executed. In all four cases, all are attempted.
+ let execution_count = if relax_intrabatch_account_locks && !use_duplicate_transaction {
+ transactions_len
+ } else {
+ 1
+ } as u64;
+
assert_eq!(
execute_and_commit_transactions_output
.transaction_counts
@@ -1339,20 +1423,29 @@ mod tests {
execute_and_commit_transactions_output
.transaction_counts
.processed_count,
- 1
+ execution_count
);
assert_eq!(
execute_and_commit_transactions_output
.transaction_counts
.processed_with_successful_result_count,
- 1
+ execution_count
);
- // Everything except first of the transactions failed and are retryable
- assert_eq!(
- execute_and_commit_transactions_output.retryable_transaction_indexes,
- (1..transactions_len).collect::>()
- );
+ // If SIMD-83 is enabled and the transactions are distinct, there are zero retryable (all executed).
+ // If SIMD-83 is enabled and the transactions are identical, there are zero retryable (marked AlreadyProcessed).
+ // If SIMD-83 is not enabled, all but the first are retryable (marked AccountInUse).
+ if relax_intrabatch_account_locks {
+ assert_eq!(
+ execute_and_commit_transactions_output.retryable_transaction_indexes,
+ Vec::::new()
+ );
+ } else {
+ assert_eq!(
+ execute_and_commit_transactions_output.retryable_transaction_indexes,
+ (1..transactions_len).collect::>()
+ );
+ }
}
#[test]
diff --git a/core/src/banking_stage/decision_maker.rs b/core/src/banking_stage/decision_maker.rs
index c355253236ffa7..7a88fbb44399ff 100644
--- a/core/src/banking_stage/decision_maker.rs
+++ b/core/src/banking_stage/decision_maker.rs
@@ -5,6 +5,7 @@ use {
HOLD_TRANSACTIONS_SLOT_OFFSET,
},
solana_pubkey::Pubkey,
+ solana_unified_scheduler_pool::{BankingStageMonitor, BankingStageStatus},
std::{
sync::{Arc, RwLock},
time::{Duration, Instant},
@@ -29,9 +30,10 @@ impl BufferedPacketsDecision {
}
}
-#[derive(Clone)]
+#[derive(Clone, derive_more::Debug)]
pub struct DecisionMaker {
my_pubkey: Pubkey,
+ #[debug("{poh_recorder:p}")]
poh_recorder: Arc>,
cached_decision: Option,
@@ -134,6 +136,19 @@ impl DecisionMaker {
}
}
+impl BankingStageMonitor for DecisionMaker {
+ fn status(&mut self) -> BankingStageStatus {
+ if matches!(
+ self.make_consume_or_forward_decision(),
+ BufferedPacketsDecision::Forward,
+ ) {
+ BankingStageStatus::Inactive
+ } else {
+ BankingStageStatus::Active
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use {
diff --git a/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs b/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs
index 0ea873dbd4953a..7f2b5d4b0fa36e 100644
--- a/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs
+++ b/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs
@@ -282,12 +282,12 @@ mod test {
},
crossbeam_channel::unbounded,
itertools::Itertools,
- solana_pubkey::Pubkey,
- solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_compute_budget_interface::ComputeBudgetInstruction,
solana_hash::Hash,
- solana_message::Message,
solana_keypair::Keypair,
+ solana_message::Message,
+ solana_pubkey::Pubkey,
+ solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_signer::Signer,
solana_system_interface::instruction as system_instruction,
solana_transaction::{sanitized::SanitizedTransaction, Transaction},
diff --git a/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs b/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs
index c898dd737148bc..35a2bcfe837033 100644
--- a/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs
+++ b/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs
@@ -24,8 +24,8 @@ use {
prio_graph::{AccessKind, GraphNode, PrioGraph},
solana_cost_model::block_cost_limits::MAX_BLOCK_UNITS,
solana_measure::measure_us,
- solana_runtime_transaction::transaction_with_meta::TransactionWithMeta,
solana_pubkey::Pubkey,
+ solana_runtime_transaction::transaction_with_meta::TransactionWithMeta,
solana_svm_transaction::svm_message::SVMMessage,
std::num::Saturating,
};
@@ -265,10 +265,10 @@ impl Scheduler for PrioGraphScheduler {
>= self.config.target_transactions_per_batch
{
num_sent += self.common.send_batch(
- &mut batches,
- thread_id,
- self.config.target_transactions_per_batch,
- )?;
+ &mut batches,
+ thread_id,
+ self.config.target_transactions_per_batch,
+ )?;
}
// if the thread is at max_cu_per_thread, remove it from the schedulable threads
@@ -291,7 +291,8 @@ impl Scheduler for PrioGraphScheduler {
}
// Send all non-empty batches
- num_sent += self.common
+ num_sent += self
+ .common
.send_batches(&mut batches, self.config.target_transactions_per_batch)?;
// Refresh window budget and do chunked pops
@@ -305,7 +306,8 @@ impl Scheduler for PrioGraphScheduler {
}
// Send batches for any remaining transactions
- num_sent += self.common
+ num_sent += self
+ .common
.send_batches(&mut batches, self.config.target_transactions_per_batch)?;
// Push unschedulable ids back into the container
@@ -433,12 +435,12 @@ mod tests {
},
crossbeam_channel::{unbounded, Receiver},
itertools::Itertools,
- solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_compute_budget_interface::ComputeBudgetInstruction,
solana_hash::Hash,
+ solana_keypair::Keypair,
solana_message::Message,
solana_pubkey::Pubkey,
- solana_keypair::Keypair,
+ solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_signer::Signer,
solana_system_interface::instruction as system_instruction,
solana_transaction::{sanitized::SanitizedTransaction, Transaction},
diff --git a/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs b/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs
index b04689383ca17a..dc1c329b7213f9 100644
--- a/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs
+++ b/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs
@@ -25,19 +25,19 @@ use {
core::time::Duration,
crossbeam_channel::{RecvTimeoutError, TryRecvError},
solana_accounts_db::account_locks::validate_account_locks,
+ solana_address_lookup_table_interface::state::estimate_last_valid_slot,
+ solana_clock::{Epoch, Slot, MAX_PROCESSING_AGE},
solana_cost_model::cost_model::CostModel,
+ solana_fee_structure::FeeBudgetLimits,
solana_measure::measure_us,
solana_runtime::{bank::Bank, bank_forks::BankForks},
solana_runtime_transaction::{
runtime_transaction::RuntimeTransaction, transaction_meta::StaticMeta,
transaction_with_meta::TransactionWithMeta,
},
- solana_address_lookup_table_interface::state::estimate_last_valid_slot,
- solana_clock::{Epoch, Slot, MAX_PROCESSING_AGE},
- solana_fee_structure::FeeBudgetLimits,
- solana_transaction::sanitized::{MessageHash, SanitizedTransaction},
solana_svm::transaction_error_metrics::TransactionErrorMetrics,
solana_svm_transaction::svm_message::SVMMessage,
+ solana_transaction::sanitized::{MessageHash, SanitizedTransaction},
std::{
num::Saturating,
sync::{Arc, RwLock},
@@ -264,7 +264,8 @@ impl SanitizedTransactionReceiveAndBuffer {
count_metrics.num_buffered += num_buffered;
count_metrics.num_dropped_on_sanitization += num_dropped_on_sanitization;
count_metrics.num_dropped_on_validate_locks += num_dropped_on_lock_validation;
- count_metrics.num_dropped_on_receive_transaction_checks += num_dropped_on_transaction_checks;
+ count_metrics.num_dropped_on_receive_transaction_checks +=
+ num_dropped_on_transaction_checks;
});
}
}
@@ -661,13 +662,13 @@ mod tests {
super::*,
crate::banking_stage::tests::create_slow_genesis_config,
crossbeam_channel::{unbounded, Receiver},
- solana_ledger::genesis_utils::GenesisConfigInfo,
- solana_perf::packet::{to_packet_batches, Packet, PacketBatch, PinnedPacketBatch},
- solana_pubkey::Pubkey,
solana_hash::Hash,
+ solana_keypair::Keypair,
+ solana_ledger::genesis_utils::GenesisConfigInfo,
solana_message::{v0, AddressLookupTableAccount, VersionedMessage},
solana_packet::{Meta, PACKET_DATA_SIZE},
- solana_keypair::Keypair,
+ solana_perf::packet::{to_packet_batches, Packet, PacketBatch, PinnedPacketBatch},
+ solana_pubkey::Pubkey,
solana_signer::Signer,
solana_system_interface::instruction as system_instruction,
solana_system_transaction::transfer,
@@ -749,8 +750,7 @@ mod tests {
calculate_max_age(sanitized_epoch, current_slot - 1, current_slot),
MaxAge {
sanitized_epoch,
- alt_invalidation_slot: current_slot - 1
- + solana_slot_hashes::get_entries() as u64,
+ alt_invalidation_slot: current_slot - 1 + solana_slot_hashes::get_entries() as u64,
}
);
diff --git a/core/src/banking_stage/transaction_scheduler/scheduler_common.rs b/core/src/banking_stage/transaction_scheduler/scheduler_common.rs
index c01ac0bca1bda0..c03792915eeea6 100644
--- a/core/src/banking_stage/transaction_scheduler/scheduler_common.rs
+++ b/core/src/banking_stage/transaction_scheduler/scheduler_common.rs
@@ -282,12 +282,10 @@ mod tests {
use {
super::*,
crate::banking_stage::transaction_scheduler::transaction_state_container::TransactionStateContainer,
- crossbeam_channel::unbounded,
- solana_keypair::Keypair,
- solana_pubkey::Pubkey,
- solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
- solana_hash::Hash, solana_system_transaction as system_transaction, solana_transaction::sanitized::SanitizedTransaction,
- test_case::test_case,
+ crossbeam_channel::unbounded, solana_hash::Hash, solana_keypair::Keypair,
+ solana_pubkey::Pubkey, solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
+ solana_system_transaction as system_transaction,
+ solana_transaction::sanitized::SanitizedTransaction, test_case::test_case,
};
const NUM_WORKERS: usize = 4;
diff --git a/core/src/banking_stage/transaction_scheduler/transaction_state.rs b/core/src/banking_stage/transaction_scheduler/transaction_state.rs
index 019ee97770182d..ecf0debf3c7e37 100644
--- a/core/src/banking_stage/transaction_scheduler/transaction_state.rs
+++ b/core/src/banking_stage/transaction_scheduler/transaction_state.rs
@@ -88,11 +88,11 @@ impl TransactionState {
mod tests {
use {
super::*,
- solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_compute_budget_interface::ComputeBudgetInstruction,
solana_hash::Hash,
- solana_message::Message,
solana_keypair::Keypair,
+ solana_message::Message,
+ solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_signer::Signer,
solana_system_interface::instruction as system_instruction,
solana_transaction::{sanitized::SanitizedTransaction, Transaction},
diff --git a/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs b/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs
index f6914621b3cc2a..bfd1419dcf1420 100644
--- a/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs
+++ b/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs
@@ -7,10 +7,10 @@ use {
itertools::MinMaxResult,
min_max_heap::MinMaxHeap,
slab::{Slab, VacantEntry},
+ solana_packet::PACKET_DATA_SIZE,
solana_runtime_transaction::{
runtime_transaction::RuntimeTransaction, transaction_with_meta::TransactionWithMeta,
},
- solana_packet::PACKET_DATA_SIZE,
std::sync::Arc,
};
@@ -346,15 +346,18 @@ mod tests {
super::*,
crate::banking_stage::scheduler_messages::MaxAge,
agave_transaction_view::transaction_view::SanitizedTransactionView,
- solana_perf::packet::Packet,
- solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_compute_budget_interface::ComputeBudgetInstruction,
solana_hash::Hash,
- solana_message::Message,
solana_keypair::Keypair,
+ solana_message::Message,
+ solana_perf::packet::Packet,
+ solana_runtime_transaction::runtime_transaction::RuntimeTransaction,
solana_signer::Signer,
solana_system_interface::instruction as system_instruction,
- solana_transaction::{sanitized::{MessageHash, SanitizedTransaction}, Transaction},
+ solana_transaction::{
+ sanitized::{MessageHash, SanitizedTransaction},
+ Transaction,
+ },
std::collections::HashSet,
};
diff --git a/core/src/banking_stage/unified_scheduler.rs b/core/src/banking_stage/unified_scheduler.rs
index 1c96065d7b3285..cf981456211591 100644
--- a/core/src/banking_stage/unified_scheduler.rs
+++ b/core/src/banking_stage/unified_scheduler.rs
@@ -54,11 +54,15 @@ pub(crate) fn ensure_banking_stage_setup(
let mut root_bank_cache = RootBankCache::new(bank_forks.clone());
let unified_receiver = channels.unified_receiver().clone();
let mut decision_maker = DecisionMaker::new(cluster_info.id(), poh_recorder.clone());
+ let banking_stage_monitor = Box::new(decision_maker.clone());
let banking_packet_handler = Box::new(
move |helper: &BankingStageHelper, batches: BankingPacketBatch| {
let decision = decision_maker.make_consume_or_forward_decision();
if matches!(decision, BufferedPacketsDecision::Forward) {
+ // discard newly-arriving packets. note that already handled packets (thus buffered
+ // by scheduler internally) will be discarded as well via BankingStageMonitor api
+ // by solScCleaner.
return;
}
let bank = root_bank_cache.root_bank();
@@ -92,5 +96,6 @@ pub(crate) fn ensure_banking_stage_setup(
unified_receiver,
banking_packet_handler,
transaction_recorder,
+ banking_stage_monitor,
);
}
diff --git a/core/src/cluster_info_vote_listener.rs b/core/src/cluster_info_vote_listener.rs
index 895efa02de8bbe..241480c7b614d9 100644
--- a/core/src/cluster_info_vote_listener.rs
+++ b/core/src/cluster_info_vote_listener.rs
@@ -1352,11 +1352,9 @@ mod tests {
let optimistically_confirmed_bank =
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
optimistically_confirmed_bank,
@@ -1477,11 +1475,9 @@ mod tests {
let optimistically_confirmed_bank =
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
optimistically_confirmed_bank,
@@ -1627,11 +1623,9 @@ mod tests {
let optimistically_confirmed_bank =
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
optimistically_confirmed_bank,
diff --git a/core/src/forwarding_stage.rs b/core/src/forwarding_stage.rs
index 06844582db9465..837ac9ad766a55 100644
--- a/core/src/forwarding_stage.rs
+++ b/core/src/forwarding_stage.rs
@@ -58,7 +58,7 @@ mod packet_container;
/// * [`TpuClientNextClient`]: Relies on the `tpu-client-next` crate.
pub enum ForwardingClientOption<'a> {
ConnectionCache(Arc),
- TpuClientNext((&'a Keypair, UdpSocket, RuntimeHandle)),
+ TpuClientNext((&'a Keypair, UdpSocket, RuntimeHandle, CancellationToken)),
}
/// Value chosen because it was used historically, at some point
@@ -153,12 +153,14 @@ pub(crate) fn spawn_forwarding_stage(
stake_identity,
tpu_client_socket,
runtime_handle,
+ cancel,
)) => {
let non_vote_client = TpuClientNextClient::new(
runtime_handle,
forward_address_getter,
Some(stake_identity),
tpu_client_socket,
+ cancel,
);
let forwarding_stage = ForwardingStage::new(
receiver,
@@ -550,10 +552,10 @@ impl TpuClientNextClient {
forward_address_getter: ForwardAddressGetter,
stake_identity: Option<&Keypair>,
bind_socket: UdpSocket,
+ cancel: CancellationToken,
) -> Self {
// For now use large channel, the more suitable size to be found later.
let (sender, receiver) = mpsc::channel(128);
- let cancel = CancellationToken::new();
let leader_updater = forward_address_getter.clone();
let config = Self::create_config(bind_socket, stake_identity);
diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs
index 05498d3b8d0702..ccc422e1b93c23 100644
--- a/core/src/replay_stage.rs
+++ b/core/src/replay_stage.rs
@@ -56,7 +56,6 @@ use {
solana_poh::poh_recorder::{PohLeaderStatus, PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS},
solana_pubkey::Pubkey,
solana_rpc::{
- block_meta_service::BlockMetaSender,
optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSenderConfig},
rpc_subscriptions::RpcSubscriptions,
slot_status_notifier::SlotStatusNotifier,
@@ -281,7 +280,6 @@ pub struct ReplaySenders {
pub rpc_subscriptions: Arc,
pub slot_status_notifier: Option,
pub transaction_status_sender: Option,
- pub block_meta_sender: Option,
pub entry_notification_sender: Option,
pub bank_notification_sender: Option,
pub ancestor_hashes_replay_update_sender: AncestorHashesReplayUpdateSender,
@@ -582,7 +580,6 @@ impl ReplayStage {
rpc_subscriptions,
slot_status_notifier,
transaction_status_sender,
- block_meta_sender,
entry_notification_sender,
bank_notification_sender,
ancestor_hashes_replay_update_sender,
@@ -740,7 +737,6 @@ impl ReplayStage {
&vote_account,
&mut progress,
transaction_status_sender.as_ref(),
- block_meta_sender.as_ref(),
entry_notification_sender.as_ref(),
&verify_recyclers,
&mut heaviest_subtree_fork_choice,
@@ -3074,7 +3070,6 @@ impl ReplayStage {
bank_forks: &RwLock,
progress: &mut ProgressMap,
transaction_status_sender: Option<&TransactionStatusSender>,
- block_meta_sender: Option<&BlockMetaSender>,
heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
bank_notification_sender: &Option,
rpc_subscriptions: &Arc,
@@ -3309,7 +3304,6 @@ impl ReplayStage {
.send(BankNotification::Frozen(bank.clone_without_scheduler()))
.unwrap_or_else(|err| warn!("bank_notification_sender failed: {:?}", err));
}
- blockstore_processor::send_block_meta(bank, block_meta_sender);
let bank_hash = bank.hash();
if let Some(new_frozen_voters) =
@@ -3374,7 +3368,6 @@ impl ReplayStage {
vote_account: &Pubkey,
progress: &mut ProgressMap,
transaction_status_sender: Option<&TransactionStatusSender>,
- block_meta_sender: Option<&BlockMetaSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
verify_recyclers: &VerifyRecyclers,
heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
@@ -3459,7 +3452,6 @@ impl ReplayStage {
bank_forks,
progress,
transaction_status_sender,
- block_meta_sender,
heaviest_subtree_fork_choice,
bank_notification_sender,
rpc_subscriptions,
@@ -4506,11 +4498,9 @@ pub(crate) mod tests {
OptimisticallyConfirmedBank::locked_from_bank_forks_root(bank_forks);
let exit = Arc::new(AtomicBool::new(false));
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let rpc_subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
Arc::new(RwLock::new(BlockCommitmentCache::default())),
optimistically_confirmed_bank,
@@ -5113,11 +5103,9 @@ pub(crate) mod tests {
&PrioritizationFeeCache::new(0u64),
);
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let rpc_subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
block_commitment_cache,
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks),
@@ -5193,11 +5181,9 @@ pub(crate) mod tests {
let exit = Arc::new(AtomicBool::new(false));
let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default()));
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let rpc_subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
block_commitment_cache.clone(),
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks),
@@ -9182,8 +9168,8 @@ pub(crate) mod tests {
&blockstore,
&replay_tx_thread_pool,
&ProcessOptions::default(),
- &recyclers,
None,
+ &recyclers,
None,
)
.unwrap();
@@ -9225,7 +9211,6 @@ pub(crate) mod tests {
&ProcessOptions::default(),
None,
None,
- None,
None, // snapshot_controller
)
.unwrap();
diff --git a/core/src/tvu.rs b/core/src/tvu.rs
index 20e8fa5a5dbd26..1b1714d0ce81b0 100644
--- a/core/src/tvu.rs
+++ b/core/src/tvu.rs
@@ -38,8 +38,7 @@ use {
solana_poh::poh_recorder::PohRecorder,
solana_pubkey::Pubkey,
solana_rpc::{
- block_meta_service::BlockMetaSender, max_slots::MaxSlots,
- optimistically_confirmed_bank_tracker::BankNotificationSenderConfig,
+ max_slots::MaxSlots, optimistically_confirmed_bank_tracker::BankNotificationSenderConfig,
rpc_subscriptions::RpcSubscriptions, slot_status_notifier::SlotStatusNotifier,
},
solana_runtime::{
@@ -143,7 +142,6 @@ impl Tvu {
block_commitment_cache: Arc>,
turbine_disabled: Arc,
transaction_status_sender: Option,
- block_meta_sender: Option,
entry_notification_sender: Option,
vote_tracker: Arc,
retransmit_slots_sender: Sender,
@@ -299,7 +297,6 @@ impl Tvu {
rpc_subscriptions: rpc_subscriptions.clone(),
slot_status_notifier,
transaction_status_sender,
- block_meta_sender,
entry_notification_sender,
bank_notification_sender,
ancestor_hashes_replay_update_sender,
@@ -524,7 +521,6 @@ pub mod tests {
let (replay_vote_sender, _replay_vote_receiver) = unbounded();
let (_, gossip_confirmed_slots_receiver) = unbounded();
let max_complete_transaction_status_slot = Arc::new(AtomicU64::default());
- let max_complete_rewards_slot = Arc::new(AtomicU64::default());
let ignored_prioritization_fee_cache = Arc::new(PrioritizationFeeCache::new(0u64));
let outstanding_repair_requests = Arc::>::default();
let cluster_slots = Arc::new(ClusterSlots::default());
@@ -563,7 +559,6 @@ pub mod tests {
&Arc::new(RpcSubscriptions::new_for_tests(
exit.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
bank_forks.clone(),
block_commitment_cache.clone(),
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks),
@@ -577,7 +572,6 @@ pub mod tests {
Arc::::default(),
None,
None,
- None,
Arc::::default(),
retransmit_slots_sender,
gossip_verified_vote_hash_receiver,
diff --git a/core/src/validator.rs b/core/src/validator.rs
index f7c995d1e3230c..17a617dc3d239a 100644
--- a/core/src/validator.rs
+++ b/core/src/validator.rs
@@ -85,7 +85,6 @@ use {
solana_pubkey::Pubkey,
solana_rayon_threadlimit::{get_max_thread_count, get_thread_count},
solana_rpc::{
- block_meta_service::{BlockMetaSender, BlockMetaService},
max_slots::MaxSlots,
optimistically_confirmed_bank_tracker::{
BankNotificationSenderConfig, OptimisticallyConfirmedBank,
@@ -146,6 +145,7 @@ use {
strum_macros::{Display, EnumCount, EnumIter, EnumString, EnumVariantNames, IntoStaticStr},
thiserror::Error,
tokio::runtime::Runtime as TokioRuntime,
+ tokio_util::sync::CancellationToken,
};
const MAX_COMPLETED_DATA_SETS_IN_CHANNEL: usize = 100_000;
@@ -366,7 +366,7 @@ impl Default for ValidatorConfig {
replay_transactions_threads: NonZeroUsize::new(1).expect("1 is non-zero"),
tvu_shred_sigverify_threads: NonZeroUsize::new(1).expect("1 is non-zero"),
delay_leader_block_for_pending_fork: false,
- use_tpu_client_next: false,
+ use_tpu_client_next: true,
retransmit_xdp: None,
}
}
@@ -479,9 +479,6 @@ struct TransactionHistoryServices {
transaction_status_sender: Option,
transaction_status_service: Option,
max_complete_transaction_status_slot: Arc,
- max_complete_rewards_slot: Arc,
- block_meta_sender: Option,
- block_meta_service: Option,
}
/// A struct easing passing Validator TPU Configurations
@@ -541,7 +538,6 @@ pub struct Validator {
rpc_completed_slots_service: Option>,
optimistically_confirmed_bank_tracker: Option,
transaction_status_service: Option,
- block_meta_service: Option,
entry_notifier_service: Option,
system_monitor_service: Option,
sample_performance_service: Option,
@@ -731,6 +727,8 @@ impl Validator {
}
}
+ // token used to cancel tpu-client-next.
+ let cancel_tpu_client_next = CancellationToken::new();
{
let exit = exit.clone();
config
@@ -738,6 +736,12 @@ impl Validator {
.write()
.unwrap()
.register_exit(Box::new(move || exit.store(true, Ordering::Relaxed)));
+ let cancel_tpu_client_next = cancel_tpu_client_next.clone();
+ config
+ .validator_exit
+ .write()
+ .unwrap()
+ .register_exit(Box::new(move || cancel_tpu_client_next.cancel()));
}
let accounts_update_notifier = geyser_plugin_service
@@ -789,9 +793,6 @@ impl Validator {
transaction_status_sender,
transaction_status_service,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
- block_meta_sender,
- block_meta_service,
},
blockstore_process_options,
blockstore_root_scan,
@@ -1011,7 +1012,6 @@ impl Validator {
&leader_schedule_cache,
&blockstore_process_options,
transaction_status_sender.as_ref(),
- block_meta_sender.clone(),
entry_notification_sender,
blockstore_root_scan,
&snapshot_controller,
@@ -1061,7 +1061,6 @@ impl Validator {
let rpc_subscriptions = Arc::new(RpcSubscriptions::new_with_config(
exit.clone(),
max_complete_transaction_status_slot.clone(),
- max_complete_rewards_slot.clone(),
blockstore.clone(),
bank_forks.clone(),
block_commitment_cache.clone(),
@@ -1177,6 +1176,7 @@ impl Validator {
Arc::as_ref(&identity_keypair),
node.sockets.rpc_sts_client,
runtime_handle.clone(),
+ cancel_tpu_client_next.clone(),
)
} else {
let Some(connection_cache) = &connection_cache else {
@@ -1204,7 +1204,6 @@ impl Validator {
max_slots: max_slots.clone(),
leader_schedule_cache: leader_schedule_cache.clone(),
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
prioritization_fee_cache: prioritization_fee_cache.clone(),
client_option,
};
@@ -1518,7 +1517,6 @@ impl Validator {
block_commitment_cache,
config.turbine_disabled.clone(),
transaction_status_sender.clone(),
- block_meta_sender,
entry_notification_sender.clone(),
vote_tracker.clone(),
retransmit_slots_sender,
@@ -1595,6 +1593,7 @@ impl Validator {
.take()
.expect("Socket should exist."),
runtime_handle.clone(),
+ cancel_tpu_client_next,
))
};
let tpu = Tpu::new_with_client(
@@ -1692,7 +1691,6 @@ impl Validator {
rpc_completed_slots_service,
optimistically_confirmed_bank_tracker,
transaction_status_service,
- block_meta_service,
entry_notifier_service,
system_monitor_service,
sample_performance_service,
@@ -1794,10 +1792,6 @@ impl Validator {
.expect("transaction_status_service");
}
- if let Some(block_meta_service) = self.block_meta_service {
- block_meta_service.join().expect("block_meta_service");
- }
-
if let Some(system_monitor_service) = self.system_monitor_service {
system_monitor_service
.join()
@@ -2120,7 +2114,9 @@ fn load_blockstore(
config.account_paths.clone(),
&config.snapshot_config,
&process_options,
- transaction_history_services.block_meta_sender.as_ref(),
+ transaction_history_services
+ .transaction_status_sender
+ .as_ref(),
entry_notifier_service
.as_ref()
.map(|service| service.sender()),
@@ -2164,7 +2160,6 @@ pub struct ProcessBlockStore<'a> {
leader_schedule_cache: &'a LeaderScheduleCache,
process_options: &'a blockstore_processor::ProcessOptions,
transaction_status_sender: Option<&'a TransactionStatusSender>,
- block_meta_sender: Option,
entry_notification_sender: Option<&'a EntryNotifierSender>,
blockstore_root_scan: Option,
snapshot_controller: &'a SnapshotController,
@@ -2184,7 +2179,6 @@ impl<'a> ProcessBlockStore<'a> {
leader_schedule_cache: &'a LeaderScheduleCache,
process_options: &'a blockstore_processor::ProcessOptions,
transaction_status_sender: Option<&'a TransactionStatusSender>,
- block_meta_sender: Option,
entry_notification_sender: Option<&'a EntryNotifierSender>,
blockstore_root_scan: BlockstoreRootScan,
snapshot_controller: &'a SnapshotController,
@@ -2200,7 +2194,6 @@ impl<'a> ProcessBlockStore<'a> {
leader_schedule_cache,
process_options,
transaction_status_sender,
- block_meta_sender,
entry_notification_sender,
blockstore_root_scan: Some(blockstore_root_scan),
snapshot_controller,
@@ -2238,7 +2231,6 @@ impl<'a> ProcessBlockStore<'a> {
self.leader_schedule_cache,
self.process_options,
self.transaction_status_sender,
- self.block_meta_sender.as_ref(),
self.entry_notification_sender,
Some(self.snapshot_controller),
)
@@ -2544,22 +2536,10 @@ fn initialize_rpc_transaction_history_services(
exit.clone(),
));
- let max_complete_rewards_slot = Arc::new(AtomicU64::new(blockstore.max_root()));
- let (block_meta_sender, block_meta_receiver) = unbounded();
- let block_meta_sender = Some(block_meta_sender);
- let block_meta_service = Some(BlockMetaService::new(
- block_meta_receiver,
- blockstore,
- max_complete_rewards_slot.clone(),
- exit,
- ));
TransactionHistoryServices {
transaction_status_sender,
transaction_status_service,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
- block_meta_sender,
- block_meta_service,
}
}
diff --git a/core/src/vote_simulator.rs b/core/src/vote_simulator.rs
index 801c671e843a02..74a4b5620933ea 100644
--- a/core/src/vote_simulator.rs
+++ b/core/src/vote_simulator.rs
@@ -142,9 +142,8 @@ impl VoteSimulator {
.any(|lockout| lockout.slot() == parent));
}
}
- while new_bank.tick_height() < new_bank.max_tick_height() {
- new_bank.register_unique_tick();
- }
+
+ new_bank.fill_bank_with_ticks_for_tests();
if !visit.node().has_no_child() || is_frozen {
new_bank.set_block_id(Some(Hash::new_unique()));
new_bank.freeze();
@@ -398,9 +397,7 @@ pub fn initialize_state(
bank0.transfer(10_000, &mint_keypair, pubkey).unwrap();
}
- while bank0.tick_height() < bank0.max_tick_height() {
- bank0.register_unique_tick();
- }
+ bank0.fill_bank_with_ticks_for_tests();
bank0.freeze();
let mut progress = ProgressMap::default();
progress.insert(
diff --git a/core/tests/snapshots.rs b/core/tests/snapshots.rs
index b1d19b0f0e8c07..c7a41ad21472f0 100644
--- a/core/tests/snapshots.rs
+++ b/core/tests/snapshots.rs
@@ -496,9 +496,7 @@ fn test_bank_forks_incremental_snapshot(
let tx = system_transaction::transfer(mint_keypair, &key, 0, bank.last_blockhash());
assert_eq!(bank.process_transaction(&tx), Ok(()));
- while !bank.is_complete() {
- bank.register_unique_tick();
- }
+ bank.fill_bank_with_ticks_for_tests();
bank_scheduler
};
@@ -783,9 +781,7 @@ fn test_snapshots_with_background_services(
let tx = system_transaction::transfer(mint_keypair, &key, 0, bank.last_blockhash());
assert_eq!(bank.process_transaction(&tx), Ok(()));
- while !bank.is_complete() {
- bank.register_unique_tick();
- }
+ bank.fill_bank_with_ticks_for_tests();
}
// Call `BankForks::set_root()` to cause snapshots to be taken
diff --git a/cost-model/Cargo.toml b/cost-model/Cargo.toml
index 265bd6ec7cccf9..ed7856f71f9147 100644
--- a/cost-model/Cargo.toml
+++ b/cost-model/Cargo.toml
@@ -9,6 +9,29 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_cost_model"
+
+[features]
+dev-context-only-utils = [
+ "dep:solana-hash",
+ "dep:solana-message",
+ "dep:solana-signature",
+ "dep:solana-transaction",
+ "solana-compute-budget-interface/dev-context-only-utils",
+]
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-compute-budget/frozen-abi",
+ "solana-pubkey/frozen-abi",
+ "solana-vote-program/frozen-abi",
+]
+
[dependencies]
agave-feature-set = { workspace = true }
ahash = { workspace = true }
@@ -41,10 +64,6 @@ solana-transaction = { workspace = true, optional = true }
solana-transaction-error = { workspace = true }
solana-vote-program = { workspace = true }
-[lib]
-crate-type = ["lib"]
-name = "solana_cost_model"
-
[dev-dependencies]
agave-reserved-account-keys = { workspace = true }
itertools = { workspace = true }
@@ -70,25 +89,6 @@ solana-vote = { workspace = true }
static_assertions = { workspace = true }
test-case = { workspace = true }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = [
- "dep:solana-hash",
- "dep:solana-message",
- "dep:solana-signature",
- "dep:solana-transaction",
- "solana-compute-budget-interface/dev-context-only-utils"
-]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-compute-budget/frozen-abi",
- "solana-pubkey/frozen-abi",
- "solana-vote-program/frozen-abi"
-]
-
[[bench]]
name = "cost_tracker"
diff --git a/curves/curve25519/Cargo.toml b/curves/curve25519/Cargo.toml
index 597e8f25603517..7beb5dc7499bbc 100644
--- a/curves/curve25519/Cargo.toml
+++ b/curves/curve25519/Cargo.toml
@@ -19,11 +19,11 @@ bytemuck_derive = { workspace = true }
subtle = { workspace = true }
thiserror = { workspace = true }
-[target.'cfg(target_os = "solana")'.dependencies]
-solana-define-syscall = { workspace = true }
-
[target.'cfg(not(target_os = "solana"))'.dependencies]
curve25519-dalek = { workspace = true, features = ["serde"] }
+[target.'cfg(target_os = "solana")'.dependencies]
+solana-define-syscall = { workspace = true }
+
[lints]
workspace = true
diff --git a/docs/src/runtime/zk-elgamal-proof.md b/docs/src/runtime/zk-elgamal-proof.md
index e3372f03f383fb..f81ca7d49cd3e4 100644
--- a/docs/src/runtime/zk-elgamal-proof.md
+++ b/docs/src/runtime/zk-elgamal-proof.md
@@ -41,7 +41,7 @@ treatment of Pedersen commitment and the (twisted) ElGamal encryption schemes.
- [Notes](https://github.com/solana-labs/solana/blob/master/docs/src/runtime/zk-docs/twisted_elgamal.pdf)
on the twisted ElGamal encryption
- A technical
- [overview](https://github.com/solana-labs/solana-program-library/blob/master/token/zk-token-protocol-paper/part1.pdf)
+ [overview](https://github.com/solana-program/token-2022/blob/main/zk-token-protocol-paper/part1.pdf)
of the SPL Token 2022 confidential extension
- Pretty Good Confidentiality [research paper](https://eprint.iacr.org/2019/319)
diff --git a/dos/Cargo.toml b/dos/Cargo.toml
index 83e40d5ff1f94d..dce537a837b429 100644
--- a/dos/Cargo.toml
+++ b/dos/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
bincode = { workspace = true }
clap = { version = "3.1.5", features = ["derive", "cargo"] }
@@ -35,7 +41,7 @@ solana-pubkey = { workspace = true }
solana-quic-client = { workspace = true }
solana-rpc = { workspace = true }
solana-rpc-client = { workspace = true }
-solana-signature = { workspace = true }
+solana-signature = { workspace = true, features = ["rand"] }
solana-signer = { workspace = true }
solana-stake-interface = { workspace = true }
solana-streamer = { workspace = true }
@@ -46,13 +52,7 @@ solana-tpu-client = { workspace = true }
solana-transaction = { workspace = true }
solana-version = { workspace = true }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
[dev-dependencies]
solana-core = { workspace = true, features = ["dev-context-only-utils"] }
solana-local-cluster = { workspace = true }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
-
-[features]
-dev-context-only-utils = []
diff --git a/download-utils/Cargo.toml b/download-utils/Cargo.toml
index 78a64d1e510cde..7d725cec277de5 100644
--- a/download-utils/Cargo.toml
+++ b/download-utils/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_download_utils"
+
[dependencies]
log = { workspace = true }
solana-clock = { workspace = true }
@@ -18,10 +25,3 @@ solana-runtime = { workspace = true }
[dev-dependencies]
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_download_utils"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/entry/Cargo.toml b/entry/Cargo.toml
index 7bca177c1c4b32..bf72e34fdf8ab8 100644
--- a/entry/Cargo.toml
+++ b/entry/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_entry"
+
[dependencies]
bincode = { workspace = true }
crossbeam-channel = { workspace = true }
@@ -42,12 +49,5 @@ solana-signer = { workspace = true }
solana-system-transaction = { workspace = true }
solana-transaction = { workspace = true, features = ["verify"] }
-[lib]
-crate-type = ["lib"]
-name = "solana_entry"
-
[[bench]]
name = "entry_sigverify"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/entry/src/poh.rs b/entry/src/poh.rs
index 2573c596053b86..0bb96307ae9bcc 100644
--- a/entry/src/poh.rs
+++ b/entry/src/poh.rs
@@ -59,6 +59,8 @@ impl Poh {
self.slot_start_time + Duration::from_nanos(offset_ns + offset_tick_ns)
}
+ /// Return `true` if the caller needs to `tick()` next, i.e. if the
+ /// remaining_hashes is 1.
pub fn hash(&mut self, max_num_hashes: u64) -> bool {
let num_hashes = std::cmp::min(self.remaining_hashes - 1, max_num_hashes);
@@ -69,7 +71,7 @@ impl Poh {
self.remaining_hashes -= num_hashes;
assert!(self.remaining_hashes > 0);
- self.remaining_hashes == 1 // Return `true` if caller needs to `tick()` next
+ self.remaining_hashes == 1
}
pub fn record(&mut self, mixin: Hash) -> Option {
@@ -88,6 +90,41 @@ impl Poh {
})
}
+ /// Returns `true` if the batches were recorded successfully and `false` if the batches
+ /// were not recorded because there were not enough hashes remaining to record all `mixins`.
+ /// If `true` is returned, the `entries` vector will be populated with the `PohEntry`s for each
+ /// batch. If `false` is returned, the `entries` vector will not be modified.
+ pub fn record_batches(&mut self, mixins: &[Hash], entries: &mut Vec) -> bool {
+ let num_mixins = mixins.len() as u64;
+ debug_assert_ne!(num_mixins, 0, "mixins.len() == 0");
+
+ if self.remaining_hashes < num_mixins + 1 {
+ return false; // Not enough hashes remaining to record all mixins
+ }
+
+ entries.clear();
+ entries.reserve(mixins.len());
+
+ // The first entry will have the current number of hashes plus one.
+ // All subsequent entries will have 1.
+ let mut num_hashes = self.num_hashes + 1;
+ entries.extend(mixins.iter().map(|mixin| {
+ self.hash = hashv(&[self.hash.as_ref(), mixin.as_ref()]);
+ let entry = PohEntry {
+ num_hashes,
+ hash: self.hash,
+ };
+
+ num_hashes = 1;
+ entry
+ }));
+
+ self.num_hashes = 0;
+ self.remaining_hashes -= num_mixins;
+
+ true
+ }
+
pub fn tick(&mut self) -> Option {
self.hash = hash(self.hash.as_ref());
self.num_hashes += 1;
@@ -330,4 +367,32 @@ mod tests {
);
assert_eq!(poh.remaining_hashes, 9);
}
+
+ #[test]
+ fn test_poh_record_batches() {
+ let mut poh = Poh::new(Hash::default(), Some(10));
+ assert!(!poh.hash(4));
+
+ let mut entries = Vec::with_capacity(3);
+ let dummy_hashes = [Hash::default(); 4];
+ assert!(poh.record_batches(&dummy_hashes[..3], &mut entries,));
+ assert_eq!(entries.len(), 3);
+ assert_eq!(entries[0].num_hashes, 5);
+ assert_eq!(entries[1].num_hashes, 1);
+ assert_eq!(entries[2].num_hashes, 1);
+ assert!(poh.remaining_hashes == 3);
+
+ // Cannot record more than number of remaining hashes
+ assert!(!poh.record_batches(&dummy_hashes[..4], &mut entries,));
+
+ // Cannot record more than number of remaining hashes
+ assert!(!poh.record_batches(&dummy_hashes[..3], &mut entries,));
+
+ // Can record less than number of remaining hashes
+ assert!(poh.record_batches(&dummy_hashes[..2], &mut entries,));
+ assert_eq!(entries.len(), 2);
+ assert_eq!(entries[0].num_hashes, 1);
+ assert_eq!(entries[1].num_hashes, 1);
+ assert!(poh.remaining_hashes == 1);
+ }
}
diff --git a/faucet/Cargo.toml b/faucet/Cargo.toml
index 62b138e5be994d..b582e383db3d87 100644
--- a/faucet/Cargo.toml
+++ b/faucet/Cargo.toml
@@ -9,6 +9,17 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_faucet"
+
+[[bin]]
+name = "solana-faucet"
+path = "src/bin/faucet.rs"
+
[dependencies]
bincode = { workspace = true }
clap = { workspace = true }
@@ -19,10 +30,10 @@ serde_derive = { workspace = true }
solana-clap-utils = { workspace = true }
solana-cli-config = { workspace = true }
solana-hash = "=2.3.0"
-solana-instruction = "=2.2.1"
+solana-instruction = "=2.3.0"
solana-keypair = "=2.2.1"
solana-logger = "=2.3.1"
-solana-message = "=2.3.0"
+solana-message = "=2.4.0"
solana-metrics = { workspace = true }
solana-native-token = "=2.2.2"
solana-packet = "=2.2.1"
@@ -35,14 +46,3 @@ solana-version = { workspace = true }
spl-memo = { version = "=6.0.0", features = ["no-entrypoint"] }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_faucet"
-
-[[bin]]
-name = "solana-faucet"
-path = "src/bin/faucet.rs"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/feature-set/Cargo.toml b/feature-set/Cargo.toml
index 84151e85357609..871d272e7b34dc 100644
--- a/feature-set/Cargo.toml
+++ b/feature-set/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "agave-feature-set"
-version = "2.3.0"
+version = "3.0.0"
description = "Solana runtime feature declarations"
authors = { workspace = true }
repository = { workspace = true }
@@ -9,6 +9,9 @@ license = { workspace = true }
edition = { workspace = true }
readme = false
+[features]
+frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"]
+
[dependencies]
ahash = { workspace = true }
solana-epoch-schedule = { workspace = true }
@@ -23,8 +26,5 @@ solana-pubkey = { workspace = true, default-features = false }
solana-sha256-hasher = { workspace = true }
solana-svm-feature-set = { workspace = true }
-[features]
-frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"]
-
[lints]
workspace = true
diff --git a/feature-set/src/lib.rs b/feature-set/src/lib.rs
index bb0b5cc72deeb1..5e241b9d83df2f 100644
--- a/feature-set/src/lib.rs
+++ b/feature-set/src/lib.rs
@@ -153,6 +153,8 @@ impl FeatureSet {
increase_tx_account_lock_limit: self.is_active(&increase_tx_account_lock_limit::id()),
disable_rent_fees_collection: self.is_active(&disable_rent_fees_collection::id()),
enable_extend_program_checked: self.is_active(&enable_extend_program_checked::id()),
+ formalize_loaded_transaction_data_size: self
+ .is_active(&formalize_loaded_transaction_data_size::id()),
}
}
}
@@ -1060,7 +1062,7 @@ pub mod drop_unchained_merkle_shreds {
}
pub mod relax_intrabatch_account_locks {
- solana_pubkey::declare_id!("EbAhnReKK8Sf88CvAfAXbgKji8DV48rsp4q2sgHqgWef");
+ solana_pubkey::declare_id!("ENTRYnPAoT5Swwx73YDGzMp3XnNH1kxacyvLosRHza1i");
}
pub mod create_slashing_program {
@@ -1095,6 +1097,10 @@ pub mod enable_extend_program_checked {
solana_pubkey::declare_id!("2oMRZEDWT2tqtYMofhmmfQ8SsjqUFzT6sYXppQDavxwz");
}
+pub mod formalize_loaded_transaction_data_size {
+ solana_pubkey::declare_id!("DeS7sR48ZcFTUmt5FFEVDr1v1bh73aAbZiZq3SYr8Eh8");
+}
+
pub static FEATURE_NAMES: LazyLock> = LazyLock::new(|| {
[
(secp256k1_program_enabled::id(), "secp256k1 program"),
@@ -1224,7 +1230,7 @@ pub static FEATURE_NAMES: LazyLock> = LazyLock::n
(check_syscall_outputs_do_not_overlap::id(), "check syscall outputs do_not overlap #28600"),
(enable_bpf_loader_set_authority_checked_ix::id(), "enable bpf upgradeable loader SetAuthorityChecked instruction #28424"),
(enable_alt_bn128_syscall::id(), "add alt_bn128 syscalls #27961"),
- (simplify_alt_bn128_syscall_error_codes::id(), "simplify alt_bn128 syscall error codes SIMD-0129"),
+ (simplify_alt_bn128_syscall_error_codes::id(), "SIMD-0129: simplify alt_bn128 syscall error codes"),
(enable_program_redeployment_cooldown::id(), "enable program redeployment cooldown #29135"),
(commission_updates_only_allowed_in_first_half_of_epoch::id(), "validator commission updates are only allowed in the first half of an epoch #29362"),
(enable_turbine_fanout_experiments::id(), "enable turbine fanout experiments #29393"),
@@ -1257,7 +1263,7 @@ pub static FEATURE_NAMES: LazyLock> = LazyLock::n
(enable_poseidon_syscall::id(), "Enable Poseidon syscall"),
(timely_vote_credits::id(), "use timeliness of votes in determining credits to award"),
(remaining_compute_units_syscall_enabled::id(), "enable the remaining_compute_units syscall"),
- (enable_loader_v4::id(), "Enable Loader-v4 SIMD-0167"),
+ (enable_loader_v4::id(), "SIMD-0167: Enable Loader-v4"),
(require_rent_exempt_split_destination::id(), "Require stake split destination account to be rent exempt"),
(better_error_codes_for_tx_lamport_check::id(), "better error codes for tx lamport check #33353"),
(enable_alt_bn128_compression_syscall::id(), "add alt_bn128 compression syscalls"),
@@ -1286,50 +1292,51 @@ pub static FEATURE_NAMES: LazyLock> = LazyLock::n
(enable_tower_sync_ix::id(), "Enable tower sync vote instruction"),
(chained_merkle_conflict_duplicate_proofs::id(), "generate duplicate proofs for chained merkle root conflicts"),
(reward_full_priority_fee::id(), "Reward full priority fee to validators #34731"),
- (abort_on_invalid_curve::id(), "Abort when elliptic curve syscalls invoked on invalid curve id SIMD-0137"),
+ (abort_on_invalid_curve::id(), "SIMD-0137: Abort when elliptic curve syscalls invoked on invalid curve id"),
(get_sysvar_syscall_enabled::id(), "Enable syscall for fetching Sysvar bytes #615"),
(migrate_feature_gate_program_to_core_bpf::id(), "Migrate Feature Gate program to Core BPF (programify) #1003"),
(vote_only_full_fec_sets::id(), "vote only full fec sets"),
(migrate_config_program_to_core_bpf::id(), "Migrate Config program to Core BPF #1378"),
(enable_get_epoch_stake_syscall::id(), "Enable syscall: sol_get_epoch_stake #884"),
(migrate_address_lookup_table_program_to_core_bpf::id(), "Migrate Address Lookup Table program to Core BPF #1651"),
- (zk_elgamal_proof_program_enabled::id(), "Enable ZkElGamalProof program SIMD-0153"),
+ (zk_elgamal_proof_program_enabled::id(), "SIMD-0153: Enable ZkElGamalProof program"),
(verify_retransmitter_signature::id(), "Verify retransmitter signature #1840"),
(move_stake_and_move_lamports_ixs::id(), "Enable MoveStake and MoveLamports stake program instructions #1610"),
- (ed25519_precompile_verify_strict::id(), "Use strict verification in ed25519 precompile SIMD-0152"),
+ (ed25519_precompile_verify_strict::id(), "SIMD-0152: Use strict verification in ed25519 precompile"),
(vote_only_retransmitter_signed_fec_sets::id(), "vote only on retransmitter signed fec sets"),
(move_precompile_verification_to_svm::id(), "SIMD-0159: Move precompile verification into SVM"),
- (enable_transaction_loading_failure_fees::id(), "Enable fees for some additional transaction failures SIMD-0082"),
+ (enable_transaction_loading_failure_fees::id(), "SIMD-0082: Enable fees for some additional transaction failures"),
(enable_turbine_extended_fanout_experiments::id(), "enable turbine extended fanout experiments #"),
(deprecate_legacy_vote_ixs::id(), "Deprecate legacy vote instructions"),
- (partitioned_epoch_rewards_superfeature::id(), "replaces enable_partitioned_epoch_reward to enable partitioned rewards at epoch boundary SIMD-0118"),
- (disable_sbpf_v0_execution::id(), "Disables execution of SBPFv1 programs SIMD-0161"),
+ (partitioned_epoch_rewards_superfeature::id(), "SIMD-0118: replaces enable_partitioned_epoch_reward to enable partitioned rewards at epoch boundary"),
+ (disable_sbpf_v0_execution::id(), "SIMD-0161: Disables execution of SBPFv1 programs"),
(reenable_sbpf_v0_execution::id(), "Re-enables execution of SBPFv1 programs"),
- (enable_sbpf_v1_deployment_and_execution::id(), "Enables deployment and execution of SBPFv1 programs SIMD-0161"),
- (enable_sbpf_v2_deployment_and_execution::id(), "Enables deployment and execution of SBPFv2 programs SIMD-0161"),
- (enable_sbpf_v3_deployment_and_execution::id(), "Enables deployment and execution of SBPFv3 programs SIMD-0161"),
- (remove_accounts_executable_flag_checks::id(), "Remove checks of accounts is_executable flag SIMD-0162"),
+ (enable_sbpf_v1_deployment_and_execution::id(), "SIMD-0161: Enables deployment and execution of SBPFv1 programs"),
+ (enable_sbpf_v2_deployment_and_execution::id(), "SIMD-0161: Enables deployment and execution of SBPFv2 programs"),
+ (enable_sbpf_v3_deployment_and_execution::id(), "SIMD-0161: Enables deployment and execution of SBPFv3 programs"),
+ (remove_accounts_executable_flag_checks::id(), "SIMD-0162: Remove checks of accounts is_executable flag"),
(lift_cpi_caller_restriction::id(), "Lift the restriction in CPI that the caller must have the callee as an instruction account #2202"),
(disable_account_loader_special_case::id(), "Disable account loader special case #3513"),
- (accounts_lt_hash::id(), "enables lattice-based accounts hash SIMD-0215"),
- (snapshots_lt_hash::id(), "snapshots use lattice-based accounts hash SIMD-0220"),
- (remove_accounts_delta_hash::id(), "removes accounts delta hash SIMD-0223"),
- (enable_secp256r1_precompile::id(), "Enable secp256r1 precompile SIMD-0075"),
- (migrate_stake_program_to_core_bpf::id(), "Migrate Stake program to Core BPF SIMD-0196 #3655"),
- (deplete_cu_meter_on_vm_failure::id(), "Deplete compute meter for vm errors SIMD-0182 #3993"),
- (reserve_minimal_cus_for_builtin_instructions::id(), "Reserve minimal CUs for builtin instructions SIMD-170 #2562"),
- (raise_block_limits_to_50m::id(), "Raise block limit to 50M SIMD-0207"),
- (fix_alt_bn128_multiplication_input_length::id(), "fix alt_bn128 multiplication input length SIMD-0222 #3686"),
+ (accounts_lt_hash::id(), "SIMD-0215: enables lattice-based accounts hash"),
+ (snapshots_lt_hash::id(), "SIMD-0220: snapshots use lattice-based accounts hash"),
+ (remove_accounts_delta_hash::id(), "SIMD-0223: removes accounts delta hash"),
+ (enable_secp256r1_precompile::id(), "SIMD-0075: Enable secp256r1 precompile"),
+ (migrate_stake_program_to_core_bpf::id(), "SIMD-0196: Migrate Stake program to Core BPF #3655"),
+ (deplete_cu_meter_on_vm_failure::id(), "SIMD-0182: Deplete compute meter for vm errors #3993"),
+ (reserve_minimal_cus_for_builtin_instructions::id(), "SIMD-0170: Reserve minimal CUs for builtin instructions #2562"),
+ (raise_block_limits_to_50m::id(), "SIMD-0207: Raise block limit to 50M"),
+ (fix_alt_bn128_multiplication_input_length::id(), "SIMD-0222: fix alt_bn128 multiplication input length #3686"),
(drop_unchained_merkle_shreds::id(), "drops unchained Merkle shreds #2149"),
- (relax_intrabatch_account_locks::id(), "Allow batched transactions to read/write and write/write the same accounts SIMD-0083"),
- (create_slashing_program::id(), "creates an enshrined slashing program SIMD-0204"),
- (disable_partitioned_rent_collection::id(), "Disable partitioned rent collection SIMD-0175 #4562"),
- (enable_vote_address_leader_schedule::id(), "Enable vote address leader schedule SIMD-0180 #4573"),
+ (relax_intrabatch_account_locks::id(), "SIMD-0083: Allow batched transactions to read/write and write/write the same accounts"),
+ (create_slashing_program::id(), "SIMD-0204: creates an enshrined slashing program"),
+ (disable_partitioned_rent_collection::id(), "SIMD-0175: Disable partitioned rent collection #4562"),
+ (enable_vote_address_leader_schedule::id(), "SIMD-0180: Enable vote address leader schedule #4573"),
(require_static_nonce_account::id(), "SIMD-0242: Static Nonce Account Only"),
- (raise_block_limits_to_60m::id(), "Raise block limit to 60M SIMD-0256"),
+ (raise_block_limits_to_60m::id(), "SIMD-0256: Raise block limit to 60M"),
(mask_out_rent_epoch_in_vm_serialization::id(), "SIMD-0267: Sets rent_epoch to a constant in the VM"),
(enshrine_slashing_program::id(), "SIMD-0204: Slashable event verification"),
(enable_extend_program_checked::id(), "Enable ExtendProgramChecked instruction"),
+ (formalize_loaded_transaction_data_size::id(), "SIMD-0186: Loaded transaction data size specification"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()
diff --git a/genesis-utils/Cargo.toml b/genesis-utils/Cargo.toml
index 6f11a8cad46d2a..f4040d34136bf0 100644
--- a/genesis-utils/Cargo.toml
+++ b/genesis-utils/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_genesis_utils"
+
[dependencies]
log = { workspace = true }
solana-accounts-db = { workspace = true }
@@ -16,10 +23,3 @@ solana-download-utils = { workspace = true }
solana-genesis-config = { workspace = true }
solana-hash = { workspace = true }
solana-rpc-client = { workspace = true }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_genesis_utils"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/genesis/Cargo.toml b/genesis/Cargo.toml
index 0f6ff8a923f7a9..6448e450bc9ba2 100644
--- a/genesis/Cargo.toml
+++ b/genesis/Cargo.toml
@@ -9,6 +9,16 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_genesis"
+
+[[bin]]
+name = "solana-genesis"
+path = "src/main.rs"
+
[dependencies]
agave-feature-set = { workspace = true }
base64 = { workspace = true }
@@ -54,13 +64,3 @@ tempfile = { workspace = true }
solana-borsh = { workspace = true }
solana-pubkey = { workspace = true, features = ["rand"] }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
-
-[[bin]]
-name = "solana-genesis"
-path = "src/main.rs"
-
-[lib]
-name = "solana_genesis"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/geyser-plugin-interface/Cargo.toml b/geyser-plugin-interface/Cargo.toml
index 465eca2c8bb6a7..6a39745cab0c6c 100644
--- a/geyser-plugin-interface/Cargo.toml
+++ b/geyser-plugin-interface/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
log = { workspace = true, features = ["std"] }
solana-clock = { workspace = true }
@@ -16,6 +19,3 @@ solana-signature = { workspace = true }
solana-transaction = { workspace = true }
solana-transaction-status = { workspace = true }
thiserror = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/geyser-plugin-manager/Cargo.toml b/geyser-plugin-manager/Cargo.toml
index 54459d54aab829..2637384dc1a331 100644
--- a/geyser-plugin-manager/Cargo.toml
+++ b/geyser-plugin-manager/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
agave-geyser-plugin-interface = { workspace = true }
bs58 = { workspace = true }
@@ -33,6 +36,3 @@ solana-transaction = { workspace = true }
solana-transaction-status = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gossip/Cargo.toml b/gossip/Cargo.toml
index 7194df16469ff6..c51c6fb22fa6f1 100644
--- a/gossip/Cargo.toml
+++ b/gossip/Cargo.toml
@@ -9,6 +9,27 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[[bin]]
+name = "solana-gossip"
+path = "src/main.rs"
+
+[features]
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-bloom/frozen-abi",
+ "solana-ledger/frozen-abi",
+ "solana-perf/frozen-abi",
+ "solana-runtime/frozen-abi",
+ "solana-short-vec/frozen-abi",
+ "solana-version/frozen-abi",
+ "solana-vote/frozen-abi",
+ "solana-vote-program/frozen-abi",
+]
+
[dependencies]
agave-feature-set = { workspace = true }
arrayvec = { workspace = true }
@@ -86,25 +107,12 @@ serial_test = { workspace = true }
solana-net-utils = { workspace = true, features = ["dev-context-only-utils"] }
solana-perf = { workspace = true, features = ["dev-context-only-utils"] }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
+solana-signature = { version = "=2.3.0", features = ["rand"] }
solana-system-transaction = { workspace = true }
solana-vote-interface = { workspace = true }
static_assertions = { workspace = true }
test-case = { workspace = true }
-[features]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-bloom/frozen-abi",
- "solana-ledger/frozen-abi",
- "solana-perf/frozen-abi",
- "solana-runtime/frozen-abi",
- "solana-short-vec/frozen-abi",
- "solana-version/frozen-abi",
- "solana-vote/frozen-abi",
- "solana-vote-program/frozen-abi",
-]
-
[[bench]]
name = "crds"
@@ -118,12 +126,5 @@ name = "crds_shards"
name = "weighted_shuffle"
harness = false
-[[bin]]
-name = "solana-gossip"
-path = "src/main.rs"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
[lints]
workspace = true
diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs
index 4d21b0dce8c6ff..ce51a0d5bbf899 100644
--- a/gossip/src/cluster_info.rs
+++ b/gossip/src/cluster_info.rs
@@ -19,6 +19,7 @@ use {
contact_info::{self, ContactInfo, ContactInfoQuery, Error as ContactInfoError},
crds::{Crds, Cursor, GossipRoute},
crds_data::{self, CrdsData, EpochSlotsIndex, LowestSlot, SnapshotHashes, Vote, MAX_VOTES},
+ crds_filter::{should_retain_crds_value, GossipFilterDirection, MIN_STAKE_TO_SKIP_PING},
crds_gossip::CrdsGossip,
crds_gossip_error::CrdsGossipError,
crds_gossip_pull::{
@@ -133,11 +134,6 @@ pub const DEFAULT_CONTACT_DEBUG_INTERVAL_MILLIS: u64 = 10_000;
pub const DEFAULT_CONTACT_SAVE_INTERVAL_MILLIS: u64 = 60_000;
// Limit number of unique pubkeys in the crds table.
pub(crate) const CRDS_UNIQUE_PUBKEY_CAPACITY: usize = 8192;
-/// Minimum stake that a node should have so that its CRDS values are
-/// propagated through gossip (few types are exempted).
-const MIN_STAKE_FOR_GOSSIP: u64 = solana_native_token::LAMPORTS_PER_SOL;
-/// Minimum number of staked nodes for enforcing stakes in gossip.
-const MIN_NUM_STAKED_NODES: usize = 500;
// Must have at least one socket to monitor the TVU port
pub const MINIMUM_NUM_TVU_RECEIVE_SOCKETS: NonZeroUsize = NonZeroUsize::new(1).unwrap();
@@ -177,42 +173,6 @@ pub struct ClusterInfo {
socket_addr_space: SocketAddrSpace,
}
-// Returns false if the CRDS value should be discarded.
-#[inline]
-#[must_use]
-fn should_retain_crds_value(
- value: &CrdsValue,
- stakes: &HashMap,
- drop_unstaked_node_instance: bool,
-) -> bool {
- match value.data() {
- CrdsData::ContactInfo(_) => true,
- CrdsData::LegacyContactInfo(_) => true,
- // May Impact new validators starting up without any stake yet.
- CrdsData::Vote(_, _) => true,
- // Unstaked nodes can still help repair.
- CrdsData::EpochSlots(_, _) => true,
- // Unstaked nodes can still serve snapshots.
- CrdsData::LegacySnapshotHashes(_) | CrdsData::SnapshotHashes(_) => true,
- // Otherwise unstaked voting nodes will show up with no version in
- // the various dashboards.
- CrdsData::Version(_) => true,
- CrdsData::AccountsHashes(_) => true,
- CrdsData::NodeInstance(_) if !drop_unstaked_node_instance => true,
- CrdsData::LowestSlot(_, _)
- | CrdsData::LegacyVersion(_)
- | CrdsData::DuplicateShred(_, _)
- | CrdsData::RestartHeaviestFork(_)
- | CrdsData::RestartLastVotedForkSlots(_)
- | CrdsData::NodeInstance(_) => {
- stakes.len() < MIN_NUM_STAKED_NODES || {
- let stake = stakes.get(&value.pubkey()).copied();
- stake.unwrap_or_default() >= MIN_STAKE_FOR_GOSSIP
- }
- }
- }
-}
-
impl ClusterInfo {
pub fn new(
contact_info: ContactInfo,
@@ -1229,7 +1189,9 @@ impl ClusterInfo {
stakes: &HashMap,
) -> impl Iterator
- {
let now = timestamp();
- let self_info = CrdsValue::new(CrdsData::from(self.my_contact_info()), &self.keypair());
+ let mut contact_info = self.my_contact_info();
+ contact_info.set_wallclock(now);
+ let self_info = CrdsValue::new(CrdsData::from(contact_info), &self.keypair());
let max_bloom_filter_bytes = get_max_bloom_filter_bytes(&self_info);
let mut pings = Vec::new();
let pulls = {
@@ -1282,9 +1244,7 @@ impl ClusterInfo {
self.flush_push_queue();
self.gossip
.new_push_messages(&self_id, timestamp(), stakes, |value| {
- should_retain_crds_value(
- value, stakes, /*drop_unstaked_node_instance:*/ false,
- )
+ should_retain_crds_value(value, stakes, GossipFilterDirection::EgressPush)
})
};
self.stats
@@ -1692,7 +1652,9 @@ impl ClusterInfo {
now,
|value| {
should_retain_crds_value(
- value, stakes, /*drop_unstaked_node_instance:*/ true,
+ value,
+ stakes,
+ GossipFilterDirection::EgressPullResponse,
)
},
self.my_shred_version(),
@@ -2132,9 +2094,7 @@ impl ClusterInfo {
&mut protocol
{
values.retain(|value| {
- should_retain_crds_value(
- value, stakes, /*drop_unstaked_node_instance:*/ false,
- )
+ should_retain_crds_value(value, stakes, GossipFilterDirection::Ingress)
});
if values.is_empty() {
return None;
@@ -3003,7 +2963,7 @@ fn verify_gossip_addr(
_ => return true, // If not a contact-info, nothing to verify.
};
// For (sufficiently) staked nodes, don't bother with ping/pong.
- if stakes.get(pubkey) >= Some(&MIN_STAKE_FOR_GOSSIP) {
+ if stakes.get(pubkey).copied() >= Some(MIN_STAKE_TO_SKIP_PING) {
return true;
}
// Invalid addresses are not verifiable.
diff --git a/gossip/src/cluster_info_metrics.rs b/gossip/src/cluster_info_metrics.rs
index ce84180e6586cd..81579fdfcb378d 100644
--- a/gossip/src/cluster_info_metrics.rs
+++ b/gossip/src/cluster_info_metrics.rs
@@ -4,6 +4,7 @@ use {
solana_clock::Slot,
solana_measure::measure::Measure,
solana_pubkey::Pubkey,
+ solana_signature::Signature,
std::{
cmp::Reverse,
collections::HashMap,
@@ -704,3 +705,12 @@ where
datapoint_trace!(name, ("slot", slot, i64), ("num_votes", num_votes, i64));
}
}
+
+/// check if first leading_zeros bits of signature are 0
+#[inline]
+pub(crate) fn should_report_message_signature(signature: &Signature, leading_zeros: u32) -> bool {
+ let Some(Ok(bytes)) = signature.as_ref().get(..8).map(<[u8; 8]>::try_from) else {
+ return false;
+ };
+ u64::from_le_bytes(bytes).trailing_zeros() >= leading_zeros
+}
diff --git a/gossip/src/contact_info.rs b/gossip/src/contact_info.rs
index c3ee9b405ef037..a9c47f2b575d58 100644
--- a/gossip/src/contact_info.rs
+++ b/gossip/src/contact_info.rs
@@ -1,6 +1,11 @@
pub use solana_client::connection_cache::Protocol;
use {
- crate::{crds_data::MAX_WALLCLOCK, legacy_contact_info::LegacyContactInfo},
+ crate::{
+ crds_data::MAX_WALLCLOCK,
+ define_tlv_enum,
+ legacy_contact_info::LegacyContactInfo,
+ tlv::{self, TlvDecodeError, TlvRecord},
+ },
assert_matches::{assert_matches, debug_assert_matches},
serde::{Deserialize, Deserializer, Serialize},
solana_pubkey::Pubkey,
@@ -39,8 +44,9 @@ const SOCKET_TAG_TPU_VOTE: u8 = 9;
const SOCKET_TAG_TPU_VOTE_QUIC: u8 = 12;
const SOCKET_TAG_TVU: u8 = 10;
const SOCKET_TAG_TVU_QUIC: u8 = 11;
-const_assert_eq!(SOCKET_CACHE_SIZE, 13);
-const SOCKET_CACHE_SIZE: usize = SOCKET_TAG_TPU_VOTE_QUIC as usize + 1usize;
+const SOCKET_TAG_ALPENGLOW: u8 = 13;
+const_assert_eq!(SOCKET_CACHE_SIZE, 14);
+const SOCKET_CACHE_SIZE: usize = SOCKET_TAG_ALPENGLOW as usize + 1usize;
// An alias for a function that reads data from a ContactInfo entry stored in
// the gossip CRDS table.
@@ -105,8 +111,19 @@ struct SocketEntry {
offset: u16, // Port offset with respect to the previous entry.
}
-#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
-enum Extension {}
+define_tlv_enum!(
+ /// TLV encoded Extensions in ContactInfo messages
+ ///
+ /// On the wire each record is: [type: u8][len: varint][bytes]
+ /// Extensions with unknown types are skipped by tlv::parse,
+ /// so new types can be added without breaking legacy code,
+ /// and support by all clients is not required.
+ ///
+ /// Always add new TLV records to the end of this enum.
+ /// Never reorder or reuse a type.
+ /// Ensure new type collisions do not happen.
+ pub(crate) enum Extension {}
+);
// As part of deserialization, self.addrs and self.sockets should be cross
// verified and self.cache needs to be populated. This type serves as a
@@ -124,8 +141,9 @@ struct ContactInfoLite {
addrs: Vec,
#[serde(with = "short_vec")]
sockets: Vec,
+ #[allow(dead_code)]
#[serde(with = "short_vec")]
- extensions: Vec,
+ extensions: Vec,
}
macro_rules! get_socket {
@@ -212,7 +230,7 @@ impl ContactInfo {
version: solana_version::Version::default(),
addrs: Vec::::default(),
sockets: Vec::::default(),
- extensions: Vec::::default(),
+ extensions: Vec::default(),
cache: EMPTY_SOCKET_ADDR_CACHE,
}
}
@@ -268,6 +286,7 @@ impl ContactInfo {
);
get_socket!(tpu_vote, SOCKET_TAG_TPU_VOTE, SOCKET_TAG_TPU_VOTE_QUIC);
get_socket!(tvu, SOCKET_TAG_TVU, SOCKET_TAG_TVU_QUIC);
+ get_socket!(alpenglow, SOCKET_TAG_ALPENGLOW);
set_socket!(set_gossip, SOCKET_TAG_GOSSIP);
set_socket!(set_rpc, SOCKET_TAG_RPC);
@@ -281,6 +300,7 @@ impl ContactInfo {
set_socket!(@multi set_serve_repair, SOCKET_TAG_SERVE_REPAIR, SOCKET_TAG_SERVE_REPAIR_QUIC);
set_socket!(@multi set_tpu_vote, SOCKET_TAG_TPU_VOTE, SOCKET_TAG_TPU_VOTE_QUIC);
set_socket!(@multi set_tvu, SOCKET_TAG_TVU, SOCKET_TAG_TVU_QUIC);
+ set_socket!(set_alpenglow, SOCKET_TAG_ALPENGLOW);
remove_socket!(
remove_serve_repair,
@@ -541,7 +561,7 @@ impl TryFrom for ContactInfo {
version,
addrs,
sockets,
- extensions,
+ extensions: tlv::parse(&extensions),
cache: EMPTY_SOCKET_ADDR_CACHE,
};
// Populate node.cache.
@@ -737,6 +757,7 @@ mod tests {
assert_matches!(ci.tpu_vote(Protocol::QUIC), None);
assert_matches!(ci.tvu(Protocol::QUIC), None);
assert_matches!(ci.tvu(Protocol::UDP), None);
+ assert_matches!(ci.alpenglow(), None);
}
#[test]
@@ -864,6 +885,10 @@ mod tests {
}
assert_eq!(node.gossip().as_ref(), sockets.get(&SOCKET_TAG_GOSSIP));
assert_eq!(node.rpc().as_ref(), sockets.get(&SOCKET_TAG_RPC));
+ assert_eq!(
+ node.alpenglow().as_ref(),
+ sockets.get(&SOCKET_TAG_ALPENGLOW)
+ );
assert_eq!(
node.rpc_pubsub().as_ref(),
sockets.get(&SOCKET_TAG_RPC_PUBSUB)
diff --git a/gossip/src/crds.rs b/gossip/src/crds.rs
index d4a62433f762d2..a808bb02b00b21 100644
--- a/gossip/src/crds.rs
+++ b/gossip/src/crds.rs
@@ -27,6 +27,7 @@
use {
crate::{
+ cluster_info_metrics::should_report_message_signature,
contact_info::ContactInfo,
crds_data::CrdsData,
crds_entry::CrdsEntry,
@@ -44,7 +45,6 @@ use {
solana_clock::Slot,
solana_hash::Hash,
solana_pubkey::Pubkey,
- solana_signature::Signature,
std::{
cmp::Ordering,
collections::{hash_map, BTreeMap, HashMap, VecDeque},
@@ -712,7 +712,8 @@ impl CrdsDataStats {
return;
};
- if should_report_message_signature(entry.value.signature()) {
+ if should_report_message_signature(entry.value.signature(), SIGNATURE_SAMPLE_LEADING_ZEROS)
+ {
datapoint_info!(
"gossip_crds_sample",
(
@@ -779,15 +780,6 @@ impl CrdsStats {
}
}
-/// check if first SIGNATURE_SAMPLE_LEADING_ZEROS bits of signature are 0
-#[inline]
-fn should_report_message_signature(signature: &Signature) -> bool {
- let Some(Ok(bytes)) = signature.as_ref().get(..8).map(<[u8; 8]>::try_from) else {
- return false;
- };
- u64::from_le_bytes(bytes).trailing_zeros() >= SIGNATURE_SAMPLE_LEADING_ZEROS
-}
-
#[cfg(test)]
mod tests {
use {
diff --git a/gossip/src/crds_filter.rs b/gossip/src/crds_filter.rs
new file mode 100644
index 00000000000000..973a5020704cc1
--- /dev/null
+++ b/gossip/src/crds_filter.rs
@@ -0,0 +1,73 @@
+use {
+ crate::{crds_data::CrdsData, crds_value::CrdsValue},
+ solana_pubkey::Pubkey,
+ std::collections::HashMap,
+};
+
+pub(crate) enum GossipFilterDirection {
+ Ingress,
+ EgressPush,
+ EgressPullResponse,
+}
+
+/// Minimum number of staked nodes for enforcing stakes in gossip.
+const MIN_NUM_STAKED_NODES: usize = 500;
+
+/// Minimum stake that a node should have so that all its CRDS values are
+/// propagated through gossip (below this only subset of CRDS is propagated).
+pub(crate) const MIN_STAKE_FOR_GOSSIP: u64 = solana_native_token::LAMPORTS_PER_SOL;
+/// Minimum stake required for a node to bypass the initial ping check when joining gossip.
+pub(crate) const MIN_STAKE_TO_SKIP_PING: u64 = 1000 * solana_native_token::LAMPORTS_PER_SOL;
+
+/// Returns false if the CRDS value should be discarded.
+/// `direction` controls whether we are looking at
+/// incoming packet (via Push or PullResponse) or
+/// we are about to make a packet
+#[inline]
+#[must_use]
+pub(crate) fn should_retain_crds_value(
+ value: &CrdsValue,
+ stakes: &HashMap,
+ direction: GossipFilterDirection,
+) -> bool {
+ let retain_if_staked = || {
+ stakes.len() < MIN_NUM_STAKED_NODES || {
+ let stake = stakes.get(&value.pubkey()).copied();
+ stake.unwrap_or_default() >= MIN_STAKE_FOR_GOSSIP
+ }
+ };
+
+ use GossipFilterDirection::*;
+ match value.data() {
+ // All nodes can send ContactInfo
+ CrdsData::ContactInfo(_) => true,
+ // Unstaked nodes can still serve snapshots.
+ CrdsData::SnapshotHashes(_) => true,
+ // Consensus related messages only allowed for staked nodes
+ CrdsData::DuplicateShred(_, _)
+ | CrdsData::LowestSlot(0, _)
+ | CrdsData::RestartHeaviestFork(_)
+ | CrdsData::RestartLastVotedForkSlots(_) => retain_if_staked(),
+ // Unstaked nodes can technically send EpochSlots, but we do not want them
+ // eating gossip bandwidth
+ CrdsData::EpochSlots(_, _) => match direction {
+ // always store if we have received them
+ // to avoid getting them again in PullResponses
+ Ingress => true,
+ // only forward if the origin is staked
+ EgressPush | EgressPullResponse => retain_if_staked(),
+ },
+ CrdsData::Vote(_, _) => match direction {
+ Ingress | EgressPush => true,
+ EgressPullResponse => retain_if_staked(),
+ },
+ // Fully deprecated messages
+ CrdsData::AccountsHashes(_) => false,
+ CrdsData::LegacyContactInfo(_) => false,
+ CrdsData::LegacySnapshotHashes(_) => false,
+ CrdsData::LegacyVersion(_) => false,
+ CrdsData::LowestSlot(1.., _) => false,
+ CrdsData::NodeInstance(_) => false,
+ CrdsData::Version(_) => false,
+ }
+}
diff --git a/gossip/src/lib.rs b/gossip/src/lib.rs
index 843890f5615473..980d9609713f8d 100644
--- a/gossip/src/lib.rs
+++ b/gossip/src/lib.rs
@@ -7,6 +7,7 @@ pub mod contact_info;
pub mod crds;
pub mod crds_data;
pub mod crds_entry;
+mod crds_filter;
pub mod crds_gossip;
pub mod crds_gossip_error;
pub mod crds_gossip_pull;
@@ -22,6 +23,8 @@ pub mod epoch_specs;
pub mod gossip_error;
pub mod gossip_service;
#[macro_use]
+mod tlv;
+#[macro_use]
mod legacy_contact_info;
pub mod ping_pong;
mod protocol;
diff --git a/gossip/src/ping_pong.rs b/gossip/src/ping_pong.rs
index 9021eb45d02796..8147169fc71886 100644
--- a/gossip/src/ping_pong.rs
+++ b/gossip/src/ping_pong.rs
@@ -1,4 +1,5 @@
use {
+ crate::cluster_info_metrics::should_report_message_signature,
lru::LruCache,
rand::{CryptoRng, Rng},
serde_big_array::BigArray,
@@ -12,13 +13,14 @@ use {
std::{
borrow::Cow,
hash::{Hash as _, Hasher},
- net::SocketAddr,
+ net::{IpAddr, SocketAddr},
time::{Duration, Instant},
},
};
const KEY_REFRESH_CADENCE: Duration = Duration::from_secs(60);
const PING_PONG_HASH_PREFIX: &[u8] = "SOLANA_PING_PONG".as_bytes();
+const PONG_SIGNATURE_SAMPLE_LEADING_ZEROS: u32 = 5;
// For backward compatibility we are using a const generic parameter here.
// N should always be >= 8 and only the first 8 bytes are used. So the new code
@@ -60,6 +62,8 @@ pub struct PingCache {
pings: LruCache<(Pubkey, SocketAddr), Instant>,
// Verified pong responses from remote nodes.
pongs: LruCache<(Pubkey, SocketAddr), Instant>,
+ // Timestamp of last ping message sent to a remote IP.
+ ping_times: LruCache,
}
impl Ping {
@@ -116,6 +120,10 @@ impl Pong {
pub fn from(&self) -> &Pubkey {
&self.from
}
+
+ pub(crate) fn signature(&self) -> &Signature {
+ &self.signature
+ }
}
impl Sanitize for Pong {
@@ -161,6 +169,7 @@ impl PingCache {
key_refresh: now,
pings: LruCache::new(cap),
pongs: LruCache::new(cap),
+ ping_times: LruCache::new(cap),
}
}
@@ -177,6 +186,19 @@ impl PingCache {
return false;
};
self.pongs.put(remote_node, now);
+ if let Some(sent_time) = self.ping_times.pop(&socket.ip()) {
+ if should_report_message_signature(
+ pong.signature(),
+ PONG_SIGNATURE_SAMPLE_LEADING_ZEROS,
+ ) {
+ let rtt = now.saturating_duration_since(sent_time);
+ datapoint_info!(
+ "ping_rtt",
+ ("peer_ip", socket.ip().to_string(), String),
+ ("rtt_us", rtt.as_micros() as i64, i64),
+ );
+ }
+ }
true
}
@@ -199,6 +221,7 @@ impl PingCache {
self.pings.put(remote_node, now);
self.maybe_refresh_key(rng, now);
let token = make_ping_token::(self.hashers[0], &remote_node);
+ self.ping_times.put(remote_node.1.ip(), Instant::now());
Some(Ping::new(token, keypair))
}
diff --git a/gossip/src/tlv.rs b/gossip/src/tlv.rs
new file mode 100644
index 00000000000000..1cc11fd6e09a7b
--- /dev/null
+++ b/gossip/src/tlv.rs
@@ -0,0 +1,169 @@
+use {
+ serde::{Deserialize, Serialize},
+ solana_short_vec as short_vec,
+};
+
+/// Type-Length-Value encoding wrapper for bincode
+#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
+pub(crate) struct TlvRecord {
+ // type
+ pub(crate) typ: u8,
+ // length and serialized bytes of the value
+ #[serde(with = "short_vec")]
+ pub(crate) bytes: Vec,
+}
+
+/// Macro that provides a quick and easy way to define TLV compatible enums
+#[macro_export]
+macro_rules! define_tlv_enum {
+ (
+ $(#[$meta:meta])*
+ $vis:vis enum $enum_name:ident {
+ $($typ:literal => $variant:ident($inner:ty)),* $(,)?
+ }
+ ) => {
+ // add the doc-comment if present
+ $(#[$meta])*
+ // define the enum itself
+ #[derive(Debug, Clone, Eq, PartialEq)]
+ $vis enum $enum_name {
+ $(
+ $variant($inner),
+ )*
+ }
+
+ // Serialize enum by first converting into TlvRecord, and then serializing that
+ impl serde::Serialize for $enum_name {
+ fn serialize
(&self, serializer: S) -> Result
+ where
+ S: serde::Serializer,
+ {
+ let tlv_rec = TlvRecord::try_from(self).map_err(|e| serde::ser::Error::custom(e))?;
+ tlv_rec.serialize(serializer)
+ }
+ }
+
+ // define conversion from TLV wire format
+ impl TryFrom<&TlvRecord> for $enum_name {
+ type Error = TlvDecodeError;
+ fn try_from(value: &TlvRecord) -> Result {
+ match value.typ {
+ $(
+ $typ => Ok(Self::$variant(bincode::deserialize::<$inner>(&value.bytes)?)),
+ )*
+ _ => Err(TlvDecodeError::UnknownType(value.typ)),
+ }
+ }
+ }
+ // define conversion into TLV wire format
+ impl TryFrom<&$enum_name> for TlvRecord {
+ type Error = bincode::Error;
+ fn try_from(value: &$enum_name) -> Result {
+ use serde::ser::Error;
+ match value {
+ $(
+ $enum_name::$variant(inner) => Ok(TlvRecord {
+ typ: $typ,
+ bytes: bincode::serialize(inner)?,
+ }),
+ )*
+ #[allow(unreachable_patterns)]
+ _ => Err(bincode::Error::custom("Unsupported enum variant")),
+ }
+ }
+ }
+ };
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum TlvDecodeError {
+ #[error("Unknown type: {0}")]
+ UnknownType(u8),
+ #[error("Malformed payload: {0}")]
+ MalformedPayload(#[from] bincode::Error),
+}
+
+/// Parses a slice of serialized TLV records into a provided type. Unsupported
+/// TLV records are ignored.
+pub(crate) fn parse<'a, T: TryFrom<&'a TlvRecord>>(entries: &'a [TlvRecord]) -> Vec {
+ entries.iter().filter_map(|v| T::try_from(v).ok()).collect()
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{
+ define_tlv_enum,
+ tlv::{TlvDecodeError, TlvRecord},
+ };
+
+ define_tlv_enum! (pub(crate) enum ExtensionNew {
+ 1=>Test(u64),
+ 2=>LegacyString(String),
+ 3=>NewString(String),
+ });
+
+ define_tlv_enum! ( pub(crate) enum ExtensionLegacy {
+ 1=>Test(u64),
+ 2=>LegacyString(String),
+ });
+
+ /// Test that TLV encoded data is backwards-compatible,
+ /// i.e. that new TLV data can be decoded by a new
+ /// receiver where possible, and skipped otherwise
+ #[test]
+ fn test_tlv_backwards_compat() {
+ let new_tlv_data = vec![
+ ExtensionNew::Test(42),
+ ExtensionNew::NewString(String::from("bla")),
+ ];
+
+ let new_bytes = bincode::serialize(&new_tlv_data).unwrap();
+ let tlv_vec: Vec = bincode::deserialize(&new_bytes).unwrap();
+ // check that both TLV are encoded correctly
+ let new: Vec = crate::tlv::parse(&tlv_vec);
+ assert!(matches!(new[0], ExtensionNew::Test(42)));
+ if let ExtensionNew::NewString(s) = &new[1] {
+ assert_eq!(s, "bla");
+ } else {
+ panic!("Wrong deserialization")
+ };
+ // Make sure legacy recover works correctly
+ let legacy: Vec = crate::tlv::parse(&tlv_vec);
+ assert!(matches!(legacy[0], ExtensionLegacy::Test(42)));
+ assert_eq!(
+ legacy.len(),
+ 1,
+ "Legacy parser should only recover 1 entry"
+ )
+ }
+
+ /// Test that TLV encoded data is forwards-compatible,
+ /// i.e. that legacy TLV data can be decoded by a new
+ /// receiver
+ #[test]
+ fn test_tlv_forward_compat() {
+ let legacy_tlv_data = vec![
+ ExtensionLegacy::Test(42),
+ ExtensionLegacy::LegacyString(String::from("foo")),
+ ];
+ let legacy_bytes = bincode::serialize(&legacy_tlv_data).unwrap();
+
+ let tlv_vec: Vec = bincode::deserialize(&legacy_bytes).unwrap();
+ // Just in case make sure that legacy data is serialized correctly
+ let legacy: Vec = crate::tlv::parse(&tlv_vec);
+ assert!(matches!(legacy[0], ExtensionLegacy::Test(42)));
+ if let ExtensionLegacy::LegacyString(s) = &legacy[1] {
+ assert_eq!(s, "foo");
+ } else {
+ panic!("Wrong deserialization")
+ };
+ // Parse the same bytes using new parser
+ let new: Vec = crate::tlv::parse(&tlv_vec);
+ assert!(matches!(new[0], ExtensionNew::Test(42)));
+ if let ExtensionNew::LegacyString(s) = &new[1] {
+ assert_eq!(s, "foo");
+ } else {
+ panic!("Wrong deserialization")
+ };
+ }
+}
diff --git a/install/Cargo.toml b/install/Cargo.toml
index bfcbc20ef51834..681d247c9c0fdd 100644
--- a/install/Cargo.toml
+++ b/install/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
atty = { workspace = true }
bincode = { workspace = true }
@@ -29,11 +32,12 @@ serde_derive = { workspace = true }
serde_yaml = { workspace = true }
serde_yaml_08 = { package = "serde_yaml", version = "0.8.26" }
solana-clap-utils = { workspace = true }
-solana-config-program-client = { workspace = true, features = ["serde"] }
+solana-config-interface = "=1.0.0"
+solana-config-program-client = { version = "=1.1.0", features = ["serde"] }
solana-hash = "=2.3.0"
solana-keypair = "=2.2.1"
solana-logger = "=2.3.1"
-solana-message = "=2.3.0"
+solana-message = "=2.4.0"
solana-pubkey = { version = "=2.4.0", default-features = false }
solana-rpc-client = { workspace = true }
solana-sha256-hasher = { workspace = true }
@@ -48,6 +52,3 @@ url = { workspace = true }
[target."cfg(windows)".dependencies]
winapi = { workspace = true, features = ["minwindef", "winuser"] }
winreg = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/install/src/command.rs b/install/src/command.rs
index c9f21c4c9e93d5..32005da6215f8b 100644
--- a/install/src/command.rs
+++ b/install/src/command.rs
@@ -9,10 +9,8 @@ use {
crossbeam_channel::unbounded,
indicatif::{ProgressBar, ProgressStyle},
serde_derive::{Deserialize, Serialize},
- solana_config_program_client::{
- get_config_data,
- instructions_bincode::{self as config_instruction, ConfigState},
- },
+ solana_config_interface::instruction::{self as config_instruction},
+ solana_config_program_client::get_config_data,
solana_hash::Hash,
solana_keypair::{read_keypair_file, signable::Signable, Keypair},
solana_message::Message,
@@ -229,14 +227,16 @@ fn new_update_manifest(
let recent_blockhash = rpc_client.get_latest_blockhash()?;
let lamports = rpc_client
- .get_minimum_balance_for_rent_exemption(SignedUpdateManifest::max_space() as usize)?;
-
- let instructions = config_instruction::create_account::(
- &from_keypair.pubkey(),
- &update_manifest_keypair.pubkey(),
- lamports,
- vec![], // additional keys
- );
+ .get_minimum_balance_for_rent_exemption(SignedUpdateManifest::MAX_SPACE as usize)?;
+
+ let instructions =
+ config_instruction::create_account_with_max_config_space::(
+ &from_keypair.pubkey(),
+ &update_manifest_keypair.pubkey(),
+ lamports,
+ SignedUpdateManifest::MAX_SPACE,
+ vec![], // additional keys
+ );
let message = Message::new(&instructions, Some(&from_keypair.pubkey()));
let signers = [from_keypair, update_manifest_keypair];
let transaction = Transaction::new(&signers, message, recent_blockhash);
diff --git a/install/src/update_manifest.rs b/install/src/update_manifest.rs
index c186dc5250bceb..11bb12a7c4f257 100644
--- a/install/src/update_manifest.rs
+++ b/install/src/update_manifest.rs
@@ -1,6 +1,5 @@
use {
serde_derive::{Deserialize, Serialize},
- solana_config_program_client::instructions_bincode::ConfigState,
solana_hash::Hash,
solana_keypair::signable::Signable,
solana_pubkey::Pubkey,
@@ -42,6 +41,8 @@ impl Signable for SignedUpdateManifest {
}
impl SignedUpdateManifest {
+ pub const MAX_SPACE: u64 = 256; // Enough space for a fully populated SignedUpdateManifest
+
pub fn deserialize(
account_pubkey: &Pubkey,
input: &[u8],
@@ -55,9 +56,3 @@ impl SignedUpdateManifest {
}
}
}
-
-impl ConfigState for SignedUpdateManifest {
- fn max_space() -> u64 {
- 256 // Enough space for a fully populated SignedUpdateManifest
- }
-}
diff --git a/keygen/Cargo.toml b/keygen/Cargo.toml
index bbd20b99dfd642..540f857dc074ba 100644
--- a/keygen/Cargo.toml
+++ b/keygen/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[[bin]]
+name = "solana-keygen"
+path = "src/keygen.rs"
+
[dependencies]
bs58 = { workspace = true }
clap = { version = "3.1.5", features = ["cargo"] }
@@ -18,9 +25,9 @@ serde_json = { workspace = true }
solana-clap-v3-utils = { workspace = true }
solana-cli-config = { workspace = true }
solana-derivation-path = "=2.2.1"
-solana-instruction = { version = "=2.2.1", features = ["bincode"] }
+solana-instruction = { version = "=2.3.0", features = ["bincode"] }
solana-keypair = "=2.2.1"
-solana-message = { version = "=2.3.0", features = ["bincode"] }
+solana-message = { version = "=2.4.0", features = ["bincode"] }
solana-pubkey = { version = "=2.4.0", default-features = false }
solana-remote-wallet = { workspace = true, features = ["default"] }
solana-seed-derivable = "=2.2.1"
@@ -31,10 +38,3 @@ tiny-bip39 = { workspace = true }
[dev-dependencies]
solana-pubkey = { workspace = true, features = ["rand"] }
tempfile = { workspace = true }
-
-[[bin]]
-name = "solana-keygen"
-path = "src/keygen.rs"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/ledger-tool/Cargo.toml b/ledger-tool/Cargo.toml
index a75135d01c979a..8fc22f13065d63 100644
--- a/ledger-tool/Cargo.toml
+++ b/ledger-tool/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
agave-feature-set = { workspace = true }
agave-reserved-account-keys = { workspace = true }
@@ -47,6 +53,7 @@ solana-geyser-plugin-manager = { workspace = true }
solana-gossip = { workspace = true }
solana-hash = { workspace = true }
solana-inflation = { workspace = true }
+solana-instruction = { workspace = true }
solana-keypair = { workspace = true }
solana-ledger = { workspace = true, features = ["dev-context-only-utils"] }
solana-loader-v3-interface = { workspace = true }
@@ -86,14 +93,8 @@ tokio = { workspace = true, features = ["full"] }
[target.'cfg(not(any(target_env = "msvc", target_os = "freebsd")))'.dependencies]
jemallocator = { workspace = true }
-[dev-dependencies]
-assert_cmd = { workspace = true }
-
-[features]
-dev-context-only-utils = []
-
[target."cfg(unix)".dependencies]
signal-hook = { workspace = true }
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
+[dev-dependencies]
+assert_cmd = { workspace = true }
diff --git a/ledger-tool/src/ledger_utils.rs b/ledger-tool/src/ledger_utils.rs
index 3ab63b7803e050..7a908238fbf3ed 100644
--- a/ledger-tool/src/ledger_utils.rs
+++ b/ledger-tool/src/ledger_utils.rs
@@ -27,9 +27,7 @@ use {
},
solana_measure::measure_time,
solana_pubkey::Pubkey,
- solana_rpc::{
- block_meta_service::BlockMetaService, transaction_status_service::TransactionStatusService,
- },
+ solana_rpc::transaction_status_service::TransactionStatusService,
solana_runtime::{
accounts_background_service::{
AbsRequestHandlers, AccountsBackgroundService, PrunedBanksRequestHandler,
@@ -294,58 +292,42 @@ pub fn load_and_process_ledger(
let enable_rpc_transaction_history = arg_matches.is_present("enable_rpc_transaction_history");
- let (
- transaction_status_sender,
- transaction_status_service,
- block_meta_sender,
- block_meta_service,
- ) = if geyser_plugin_active || enable_rpc_transaction_history {
- // Need Primary (R/W) access to insert transaction and rewards data;
- // obtain Primary access if we do not already have it
- let write_blockstore = if enable_rpc_transaction_history && !blockstore.is_primary_access()
- {
- Arc::new(open_blockstore(
- blockstore.ledger_path(),
- arg_matches,
- AccessType::PrimaryForMaintenance,
- ))
+ let (transaction_status_sender, transaction_status_service) =
+ if geyser_plugin_active || enable_rpc_transaction_history {
+ // Need Primary (R/W) access to insert transaction and rewards data;
+ // obtain Primary access if we do not already have it
+ let write_blockstore =
+ if enable_rpc_transaction_history && !blockstore.is_primary_access() {
+ Arc::new(open_blockstore(
+ blockstore.ledger_path(),
+ arg_matches,
+ AccessType::PrimaryForMaintenance,
+ ))
+ } else {
+ blockstore.clone()
+ };
+
+ let (transaction_status_sender, transaction_status_receiver) = unbounded();
+ let transaction_status_service = TransactionStatusService::new(
+ transaction_status_receiver,
+ Arc::default(),
+ enable_rpc_transaction_history,
+ transaction_notifier,
+ write_blockstore.clone(),
+ arg_matches.is_present("enable_extended_tx_metadata_storage"),
+ tss_exit.clone(),
+ );
+
+ (
+ Some(TransactionStatusSender {
+ sender: transaction_status_sender,
+ }),
+ Some(transaction_status_service),
+ )
} else {
- blockstore.clone()
+ (transaction_status_sender, None)
};
- let (transaction_status_sender, transaction_status_receiver) = unbounded();
- let transaction_status_service = TransactionStatusService::new(
- transaction_status_receiver,
- Arc::default(),
- enable_rpc_transaction_history,
- transaction_notifier,
- write_blockstore.clone(),
- arg_matches.is_present("enable_extended_tx_metadata_storage"),
- tss_exit.clone(),
- );
-
- let (block_meta_sender, block_meta_receiver) = unbounded();
- // Nothing else will be interacting with max_complete_rewards_slot
- let max_complete_rewards_slot = Arc::default();
- let block_meta_service = BlockMetaService::new(
- block_meta_receiver,
- write_blockstore,
- max_complete_rewards_slot,
- exit.clone(),
- );
-
- (
- Some(TransactionStatusSender {
- sender: transaction_status_sender,
- }),
- Some(transaction_status_service),
- Some(block_meta_sender),
- Some(block_meta_service),
- )
- } else {
- (transaction_status_sender, None, None, None)
- };
-
let (bank_forks, leader_schedule_cache, starting_snapshot_hashes, ..) =
bank_forks_utils::load_bank_forks(
genesis_config,
@@ -353,7 +335,7 @@ pub fn load_and_process_ledger(
account_paths,
&snapshot_config,
&process_options,
- block_meta_sender.as_ref(),
+ transaction_status_sender.as_ref(),
None, // Maybe support this later, though
accounts_update_notifier,
exit.clone(),
@@ -438,7 +420,6 @@ pub fn load_and_process_ledger(
&leader_schedule_cache,
&process_options,
transaction_status_sender.as_ref(),
- block_meta_sender.as_ref(),
None, // entry_notification_sender
Some(&snapshot_controller),
)
@@ -454,9 +435,6 @@ pub fn load_and_process_ledger(
if let Some(service) = transaction_status_service {
service.quiesce_and_join_for_tests(tss_exit);
}
- if let Some(service) = block_meta_service {
- service.join().unwrap();
- }
result
}
diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs
index c7f26c05182b89..f13ea3b53600cd 100644
--- a/ledger-tool/src/main.rs
+++ b/ledger-tool/src/main.rs
@@ -45,6 +45,7 @@ use {
solana_feature_gate_interface::{self as feature, Feature},
solana_genesis_config::ClusterType,
solana_inflation::Inflation,
+ solana_instruction::TRANSACTION_LEVEL_STACK_HEIGHT,
solana_ledger::{
blockstore::{banking_trace_path, create_new_ledger, Blockstore},
blockstore_options::{AccessType, LedgerColumnOptions},
@@ -754,7 +755,13 @@ fn record_transactions(
let instructions = message
.instructions()
.iter()
- .map(|ix| parse_ui_instruction(ix, &message.account_keys(), None))
+ .map(|ix| {
+ parse_ui_instruction(
+ ix,
+ &message.account_keys(),
+ Some(TRANSACTION_LEVEL_STACK_HEIGHT as u32),
+ )
+ })
.collect();
let is_simple_vote_tx = tx.is_simple_vote_transaction();
@@ -2331,9 +2338,7 @@ fn main() {
}
if child_bank_required {
- while !bank.is_complete() {
- bank.register_unique_tick();
- }
+ bank.fill_bank_with_ticks_for_tests();
}
let pre_capitalization = bank.capitalization();
diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml
index 9b600c4346b617..7e99d3146c75bb 100644
--- a/ledger/Cargo.toml
+++ b/ledger/Cargo.toml
@@ -9,6 +9,21 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_ledger"
+
+[features]
+dev-context-only-utils = []
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-runtime/frozen-abi",
+]
+
[dependencies]
agave-feature-set = { workspace = true }
agave-reserved-account-keys = { workspace = true }
@@ -125,23 +140,12 @@ solana-perf = { workspace = true, features = ["dev-context-only-utils"] }
solana-program-option = { workspace = true }
solana-program-pack = { workspace = true }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
+solana-signature = { workspace = true, features = ["rand"] }
solana-vote = { workspace = true, features = ["dev-context-only-utils"] }
spl-generic-token = { workspace = true }
spl-pod = { workspace = true }
test-case = { workspace = true }
-[features]
-dev-context-only-utils = []
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-runtime/frozen-abi",
-]
-
-[lib]
-crate-type = ["lib"]
-name = "solana_ledger"
-
[[bench]]
name = "blockstore"
@@ -149,8 +153,5 @@ name = "blockstore"
name = "make_shreds_from_entries"
harness = false
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
[lints]
workspace = true
diff --git a/ledger/src/bank_forks_utils.rs b/ledger/src/bank_forks_utils.rs
index 96816099da1a84..d2e882471656a8 100644
--- a/ledger/src/bank_forks_utils.rs
+++ b/ledger/src/bank_forks_utils.rs
@@ -2,8 +2,7 @@ use {
crate::{
blockstore::Blockstore,
blockstore_processor::{
- self, BlockMetaSender, BlockstoreProcessorError, ProcessOptions,
- TransactionStatusSender,
+ self, BlockstoreProcessorError, ProcessOptions, TransactionStatusSender,
},
entry_notifier_service::EntryNotifierSender,
leader_schedule_cache::LeaderScheduleCache,
@@ -85,7 +84,6 @@ pub fn load(
snapshot_config: &SnapshotConfig,
process_options: ProcessOptions,
transaction_status_sender: Option<&TransactionStatusSender>,
- block_meta_sender: Option<&BlockMetaSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
accounts_update_notifier: Option,
exit: Arc,
@@ -96,7 +94,7 @@ pub fn load(
account_paths,
snapshot_config,
&process_options,
- block_meta_sender,
+ transaction_status_sender,
entry_notification_sender,
accounts_update_notifier,
exit,
@@ -107,7 +105,6 @@ pub fn load(
&leader_schedule_cache,
&process_options,
transaction_status_sender,
- block_meta_sender,
entry_notification_sender,
None, // snapshot_controller
)
@@ -123,7 +120,7 @@ pub fn load_bank_forks(
account_paths: Vec,
snapshot_config: &SnapshotConfig,
process_options: &ProcessOptions,
- block_meta_sender: Option<&BlockMetaSender>,
+ transaction_status_sender: Option<&TransactionStatusSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
accounts_update_notifier: Option,
exit: Arc,
@@ -191,7 +188,7 @@ pub fn load_bank_forks(
blockstore,
account_paths,
process_options,
- block_meta_sender,
+ transaction_status_sender,
entry_notification_sender,
accounts_update_notifier,
exit,
diff --git a/ledger/src/bigtable_upload_service.rs b/ledger/src/bigtable_upload_service.rs
index 0ffb02aac2475c..fbafe160afc86a 100644
--- a/ledger/src/bigtable_upload_service.rs
+++ b/ledger/src/bigtable_upload_service.rs
@@ -26,7 +26,6 @@ impl BigTableUploadService {
blockstore: Arc,
block_commitment_cache: Arc>,
max_complete_transaction_status_slot: Arc,
- max_complete_rewards_slot: Arc,
exit: Arc,
) -> Self {
Self::new_with_config(
@@ -35,7 +34,6 @@ impl BigTableUploadService {
blockstore,
block_commitment_cache,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
ConfirmedBlockUploadConfig::default(),
exit,
)
@@ -47,7 +45,6 @@ impl BigTableUploadService {
blockstore: Arc,
block_commitment_cache: Arc>,
max_complete_transaction_status_slot: Arc,
- max_complete_rewards_slot: Arc,
config: ConfirmedBlockUploadConfig,
exit: Arc,
) -> Self {
@@ -61,7 +58,6 @@ impl BigTableUploadService {
blockstore,
block_commitment_cache,
max_complete_transaction_status_slot,
- max_complete_rewards_slot,
config,
exit,
)
@@ -77,7 +73,6 @@ impl BigTableUploadService {
blockstore: Arc,
block_commitment_cache: Arc>,
max_complete_transaction_status_slot: Arc,
- max_complete_rewards_slot: Arc,
config: ConfirmedBlockUploadConfig,
exit: Arc,
) {
@@ -87,16 +82,12 @@ impl BigTableUploadService {
break;
}
- // The highest slot eligible for upload is the highest root that has complete
- // transaction-status metadata and rewards
- let highest_complete_root = [
+ // The highest slot eligible for upload is the highest root that
+ // has complete block metadata
+ let highest_complete_root = std::cmp::min(
max_complete_transaction_status_slot.load(Ordering::SeqCst),
- max_complete_rewards_slot.load(Ordering::SeqCst),
block_commitment_cache.read().unwrap().root(),
- ]
- .into_iter()
- .min()
- .expect("root and max_complete slots exist");
+ );
let end_slot = min(
highest_complete_root,
start_slot.saturating_add(config.max_num_slots_to_check as u64 * 2),
diff --git a/ledger/src/blockstore_processor.rs b/ledger/src/blockstore_processor.rs
index 352e1ad5d7801a..73f0e568b04861 100644
--- a/ledger/src/blockstore_processor.rs
+++ b/ledger/src/blockstore_processor.rs
@@ -929,7 +929,6 @@ pub fn test_process_blockstore(
opts,
None,
None,
- None,
Some(&snapshot_controller),
)
.unwrap();
@@ -945,7 +944,7 @@ pub(crate) fn process_blockstore_for_bank_0(
blockstore: &Blockstore,
account_paths: Vec,
opts: &ProcessOptions,
- block_meta_sender: Option<&BlockMetaSender>,
+ transaction_status_sender: Option<&TransactionStatusSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
accounts_update_notifier: Option,
exit: Arc,
@@ -979,8 +978,8 @@ pub(crate) fn process_blockstore_for_bank_0(
blockstore,
&replay_tx_thread_pool,
opts,
+ transaction_status_sender,
&VerifyRecyclers::default(),
- block_meta_sender,
entry_notification_sender,
)?;
@@ -995,7 +994,6 @@ pub fn process_blockstore_from_root(
leader_schedule_cache: &LeaderScheduleCache,
opts: &ProcessOptions,
transaction_status_sender: Option<&TransactionStatusSender>,
- block_meta_sender: Option<&BlockMetaSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
snapshot_controller: Option<&SnapshotController>,
) -> result::Result<(), BlockstoreProcessorError> {
@@ -1061,7 +1059,6 @@ pub fn process_blockstore_from_root(
leader_schedule_cache,
opts,
transaction_status_sender,
- block_meta_sender,
entry_notification_sender,
&mut timing,
snapshot_controller,
@@ -1771,8 +1768,8 @@ fn process_bank_0(
blockstore: &Blockstore,
replay_tx_thread_pool: &ThreadPool,
opts: &ProcessOptions,
+ transaction_status_sender: Option<&TransactionStatusSender>,
recyclers: &VerifyRecyclers,
- block_meta_sender: Option<&BlockMetaSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
) -> result::Result<(), BlockstoreProcessorError> {
assert_eq!(bank0.slot(), 0);
@@ -1797,7 +1794,10 @@ fn process_bank_0(
if blockstore.is_primary_access() {
blockstore.insert_bank_hash(bank0.slot(), bank0.hash(), false);
}
- send_block_meta(bank0, block_meta_sender);
+
+ if let Some(transaction_status_sender) = transaction_status_sender {
+ transaction_status_sender.send_transaction_status_freeze_message(bank0);
+ }
Ok(())
}
@@ -1874,7 +1874,6 @@ fn load_frozen_forks(
leader_schedule_cache: &LeaderScheduleCache,
opts: &ProcessOptions,
transaction_status_sender: Option<&TransactionStatusSender>,
- block_meta_sender: Option<&BlockMetaSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
timing: &mut ExecuteTimings,
snapshot_controller: Option<&SnapshotController>,
@@ -1958,7 +1957,6 @@ fn load_frozen_forks(
&recyclers,
&mut progress,
transaction_status_sender,
- block_meta_sender,
entry_notification_sender,
None,
timing,
@@ -2149,7 +2147,6 @@ pub fn process_single_slot(
recyclers: &VerifyRecyclers,
progress: &mut ConfirmationProgress,
transaction_status_sender: Option<&TransactionStatusSender>,
- block_meta_sender: Option<&BlockMetaSender>,
entry_notification_sender: Option<&EntryNotifierSender>,
replay_vote_sender: Option<&ReplayVoteSender>,
timing: &mut ExecuteTimings,
@@ -2214,7 +2211,10 @@ pub fn process_single_slot(
if blockstore.is_primary_access() {
blockstore.insert_bank_hash(bank.slot(), bank.hash(), false);
}
- send_block_meta(bank, block_meta_sender);
+
+ if let Some(transaction_status_sender) = transaction_status_sender {
+ transaction_status_sender.send_transaction_status_freeze_message(bank);
+ }
Ok(())
}
@@ -2223,7 +2223,7 @@ pub fn process_single_slot(
#[derive(Debug)]
pub enum TransactionStatusMessage {
Batch(TransactionStatusBatch),
- Freeze(Slot),
+ Freeze(Arc),
}
#[derive(Debug)]
@@ -2274,27 +2274,19 @@ impl TransactionStatusSender {
}
pub fn send_transaction_status_freeze_message(&self, bank: &Arc) {
- let slot = bank.slot();
- if let Err(e) = self.sender.send(TransactionStatusMessage::Freeze(slot)) {
- trace!(
- "Slot {} transaction_status send freeze message failed: {:?}",
- slot,
+ if let Err(e) = self
+ .sender
+ .send(TransactionStatusMessage::Freeze(bank.clone()))
+ {
+ let slot = bank.slot();
+ warn!(
+ "Slot {slot} transaction_status send freeze message failed: {:?}",
e
);
}
}
}
-pub type BlockMetaSender = Sender>;
-
-pub fn send_block_meta(bank: &Arc, block_meta_sender: Option<&BlockMetaSender>) {
- if let Some(block_meta_sender) = block_meta_sender {
- block_meta_sender
- .send(bank.clone())
- .unwrap_or_else(|err| warn!("block_meta_sender failed: {:?}", err));
- }
-}
-
// used for tests only
pub fn fill_blockstore_slot_with_ticks(
blockstore: &Blockstore,
@@ -3638,8 +3630,11 @@ pub mod tests {
});
}
- #[test]
- fn test_process_entries_2nd_entry_collision_with_self_and_error() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_process_entries_2nd_entry_collision_with_self_and_error(
+ relax_intrabatch_account_locks: bool,
+ ) {
solana_logger::setup();
let GenesisConfigInfo {
@@ -3647,7 +3642,11 @@ pub mod tests {
mint_keypair,
..
} = create_genesis_config(1000);
- let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
+ let mut bank = Bank::new_for_tests(&genesis_config);
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
+ let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
let keypair1 = Keypair::new();
let keypair2 = Keypair::new();
let keypair3 = Keypair::new();
@@ -3687,7 +3686,7 @@ pub mod tests {
&mint_keypair.pubkey(),
2,
bank.last_blockhash(),
- ), // will collide with predecessor
+ ), // will collide with preceding entry
],
);
// should now be:
@@ -3710,28 +3709,100 @@ pub mod tests {
&keypair2.pubkey(),
1,
bank.last_blockhash(),
- ), // should be fine
+ ), // will collide with preceding transaction
],
);
- // would now be:
+ // if successful, becomes:
// keypair1=0
// keypair2=3
// keypair3=3
- assert!(process_entries_for_tests_without_scheduler(
+ // succeeds following simd83 locking, fails otherwise
+ let result = process_entries_for_tests_without_scheduler(
&bank,
vec![
entry_1_to_mint,
entry_2_to_3_and_1_to_mint,
entry_conflict_itself,
],
- )
- .is_err());
+ );
- // last entry should have been aborted before par_execute_entries
- assert_eq!(bank.get_balance(&keypair1.pubkey()), 2);
- assert_eq!(bank.get_balance(&keypair2.pubkey()), 2);
- assert_eq!(bank.get_balance(&keypair3.pubkey()), 2);
+ let balances = [
+ bank.get_balance(&keypair1.pubkey()),
+ bank.get_balance(&keypair2.pubkey()),
+ bank.get_balance(&keypair3.pubkey()),
+ ];
+
+ if relax_intrabatch_account_locks {
+ assert!(result.is_ok());
+ assert_eq!(balances, [0, 3, 3]);
+ } else {
+ assert!(result.is_err());
+ assert_eq!(balances, [2, 2, 2]);
+ }
+ }
+
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_process_entry_duplicate_transaction(relax_intrabatch_account_locks: bool) {
+ solana_logger::setup();
+
+ let GenesisConfigInfo {
+ genesis_config,
+ mint_keypair,
+ ..
+ } = create_genesis_config(1000);
+ let mut bank = Bank::new_for_tests(&genesis_config);
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
+ let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
+ let keypair1 = Keypair::new();
+ let keypair2 = Keypair::new();
+
+ // fund: put some money in each of 1 and 2
+ assert_matches!(bank.transfer(5, &mint_keypair, &keypair1.pubkey()), Ok(_));
+ assert_matches!(bank.transfer(5, &mint_keypair, &keypair2.pubkey()), Ok(_));
+
+ // one entry, two instances of the same transaction. this entry is invalid
+ // without simd83: due to lock conflicts
+ // with simd83: due to message hash duplication
+ let entry_1_to_2_twice = next_entry(
+ &bank.last_blockhash(),
+ 1,
+ vec![
+ system_transaction::transfer(
+ &keypair1,
+ &keypair2.pubkey(),
+ 1,
+ bank.last_blockhash(),
+ ),
+ system_transaction::transfer(
+ &keypair1,
+ &keypair2.pubkey(),
+ 1,
+ bank.last_blockhash(),
+ ),
+ ],
+ );
+ // should now be:
+ // keypair1=5
+ // keypair2=5
+
+ // succeeds following simd83 locking, fails otherwise
+ let result = process_entries_for_tests_without_scheduler(&bank, vec![entry_1_to_2_twice]);
+
+ let balances = [
+ bank.get_balance(&keypair1.pubkey()),
+ bank.get_balance(&keypair2.pubkey()),
+ ];
+
+ assert_eq!(balances, [5, 5]);
+ if relax_intrabatch_account_locks {
+ assert_eq!(result, Err(TransactionError::AlreadyProcessed));
+ } else {
+ assert_eq!(result, Err(TransactionError::AccountInUse));
+ }
}
#[test]
@@ -4041,14 +4112,19 @@ pub mod tests {
);
}
- #[test]
- fn test_update_transaction_statuses_fail() {
+ #[test_case(false; "old")]
+ #[test_case(true; "simd83")]
+ fn test_update_transaction_statuses_fail(relax_intrabatch_account_locks: bool) {
let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_genesis_config(11_000);
- let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
+ let mut bank = Bank::new_for_tests(&genesis_config);
+ if !relax_intrabatch_account_locks {
+ bank.deactivate_feature(&agave_feature_set::relax_intrabatch_account_locks::id());
+ }
+ let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
let keypair1 = Keypair::new();
let keypair2 = Keypair::new();
let success_tx = system_transaction::transfer(
@@ -4057,7 +4133,7 @@ pub mod tests {
1,
bank.last_blockhash(),
);
- let fail_tx = system_transaction::transfer(
+ let test_tx = system_transaction::transfer(
&mint_keypair,
&keypair2.pubkey(),
2,
@@ -4069,17 +4145,29 @@ pub mod tests {
1,
vec![
success_tx,
- fail_tx.clone(), // will collide
+ test_tx.clone(), // will collide
],
);
+ // succeeds with simd83, fails because of account locking conflict otherwise
assert_eq!(
process_entries_for_tests_without_scheduler(&bank, vec![entry_1_to_mint]),
- Err(TransactionError::AccountInUse)
+ if relax_intrabatch_account_locks {
+ Ok(())
+ } else {
+ Err(TransactionError::AccountInUse)
+ }
);
- // Should not see duplicate signature error
- assert_eq!(bank.process_transaction(&fail_tx), Ok(()));
+ // fails with simd83 as already processed, succeeds otherwise
+ assert_eq!(
+ bank.process_transaction(&test_tx),
+ if relax_intrabatch_account_locks {
+ Err(TransactionError::AlreadyProcessed)
+ } else {
+ Ok(())
+ }
+ );
}
#[test]
@@ -4166,8 +4254,8 @@ pub mod tests {
&blockstore,
&replay_tx_thread_pool,
&opts,
- &recyclers,
None,
+ &recyclers,
None,
)
.unwrap();
@@ -4202,7 +4290,6 @@ pub mod tests {
&opts,
None,
None,
- None,
None, // snapshot_controller
)
.unwrap();
diff --git a/local-cluster/Cargo.toml b/local-cluster/Cargo.toml
index cbb8ccc6d637dc..36911ac92946b0 100644
--- a/local-cluster/Cargo.toml
+++ b/local-cluster/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
crossbeam-channel = { workspace = true }
itertools = { workspace = true }
@@ -75,9 +81,3 @@ solana-download-utils = { workspace = true }
solana-ledger = { workspace = true, features = ["dev-context-only-utils"] }
solana-local-cluster = { path = ".", features = ["dev-context-only-utils"] }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[features]
-dev-context-only-utils = []
diff --git a/local-cluster/tests/local_cluster.rs b/local-cluster/tests/local_cluster.rs
index 05dfa912503c11..9314b662b5fcff 100644
--- a/local-cluster/tests/local_cluster.rs
+++ b/local-cluster/tests/local_cluster.rs
@@ -2330,7 +2330,6 @@ fn create_snapshot_to_hard_fork(
None,
None,
None,
- None,
Arc::default(),
)
.unwrap();
diff --git a/log-analyzer/Cargo.toml b/log-analyzer/Cargo.toml
index c40cce53aea91f..27c95c9b7ed5ba 100644
--- a/log-analyzer/Cargo.toml
+++ b/log-analyzer/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[[bin]]
+name = "solana-log-analyzer"
+path = "src/main.rs"
+
[dependencies]
byte-unit = { workspace = true }
clap = { version = "3.1.5", features = ["cargo"] }
@@ -17,10 +24,3 @@ serde_derive = { workspace = true }
serde_json = { workspace = true }
solana-logger = "=2.3.1"
solana-version = { workspace = true }
-
-[[bin]]
-name = "solana-log-analyzer"
-path = "src/main.rs"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/log-collector/Cargo.toml b/log-collector/Cargo.toml
index e22c14c09f65e4..693d5fd6b4812f 100644
--- a/log-collector/Cargo.toml
+++ b/log-collector/Cargo.toml
@@ -9,8 +9,8 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
-[dependencies]
-log = { workspace = true }
-
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+log = { workspace = true }
diff --git a/merkle-tree/Cargo.toml b/merkle-tree/Cargo.toml
index cbd11a0e65797c..7993e255807e12 100644
--- a/merkle-tree/Cargo.toml
+++ b/merkle-tree/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_merkle_tree"
+
[dependencies]
fast-math = { workspace = true }
solana-hash = { workspace = true }
@@ -16,10 +23,3 @@ solana-sha256-hasher = { workspace = true }
[dev-dependencies]
hex = { workspace = true }
-
-[lib]
-crate-type = ["lib"]
-name = "solana_merkle_tree"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/metrics/Cargo.toml b/metrics/Cargo.toml
index 716f4ee0ca041d..d81b5f61a73444 100644
--- a/metrics/Cargo.toml
+++ b/metrics/Cargo.toml
@@ -9,6 +9,12 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_metrics"
+
[dependencies]
crossbeam-channel = { workspace = true }
gethostname = { workspace = true }
@@ -24,11 +30,5 @@ env_logger = { workspace = true }
rand = { workspace = true }
serial_test = { workspace = true }
-[lib]
-name = "solana_metrics"
-
[[bench]]
name = "metrics"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/net-shaper/Cargo.toml b/net-shaper/Cargo.toml
index 33c4e303873462..ff047038c29beb 100644
--- a/net-shaper/Cargo.toml
+++ b/net-shaper/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[[bin]]
+name = "solana-net-shaper"
+path = "src/main.rs"
+
[dependencies]
clap = { version = "3.1.5", features = ["cargo"] }
rand = { workspace = true }
@@ -16,10 +23,3 @@ serde = { workspace = true }
serde_derive = { workspace = true }
serde_json = { workspace = true }
solana-logger = "=2.3.1"
-
-[[bin]]
-name = "solana-net-shaper"
-path = "src/main.rs"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/net-utils/Cargo.toml b/net-utils/Cargo.toml
index 89f91d22c740ce..f26dcbf7f7e207 100644
--- a/net-utils/Cargo.toml
+++ b/net-utils/Cargo.toml
@@ -10,8 +10,15 @@ license = { workspace = true }
edition = { workspace = true }
rust-version = "1.83.0"
-[lints]
-workspace = true
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_net_utils"
+
+[features]
+default = []
+dev-context-only-utils = ["dep:pcap-file", "dep:hxdmp"]
[dependencies]
anyhow = { workspace = true }
@@ -33,12 +40,5 @@ url = { workspace = true }
[dev-dependencies]
solana-logger = { workspace = true }
-[features]
-default = []
-dev-context-only-utils = ["dep:pcap-file", "dep:hxdmp"]
-
-[lib]
-name = "solana_net_utils"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
+[lints]
+workspace = true
diff --git a/notifier/Cargo.toml b/notifier/Cargo.toml
index 270ba43d9c696c..ba5dcb2a74e3a4 100644
--- a/notifier/Cargo.toml
+++ b/notifier/Cargo.toml
@@ -9,14 +9,14 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_notifier"
+
[dependencies]
log = { workspace = true }
reqwest = { workspace = true, features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] }
serde_json = { workspace = true }
solana-hash = { workspace = true }
-
-[lib]
-name = "solana_notifier"
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/perf/Cargo.toml b/perf/Cargo.toml
index 05a46eceb9db92..aa43ba4ecd4c38 100644
--- a/perf/Cargo.toml
+++ b/perf/Cargo.toml
@@ -9,6 +9,30 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "solana_perf"
+
+[features]
+dev-context-only-utils = [
+ "dep:solana-clock",
+ "dep:solana-keypair",
+ "dep:solana-signer",
+ "dep:solana-system-interface",
+ "dep:solana-system-transaction",
+ "dep:solana-transaction",
+ "dep:solana-vote-program",
+ "dep:solana-vote",
+]
+frozen-abi = [
+ "dep:solana-frozen-abi",
+ "dep:solana-frozen-abi-macro",
+ "solana-short-vec/frozen-abi",
+ "solana-vote-program/frozen-abi",
+]
+
[dependencies]
ahash = { workspace = true }
bincode = { workspace = true }
@@ -51,9 +75,6 @@ caps = { workspace = true }
libc = { workspace = true }
nix = { workspace = true, features = ["user"] }
-[lib]
-name = "solana_perf"
-
[dev-dependencies]
assert_matches = { workspace = true }
rand_chacha = { workspace = true }
@@ -61,33 +82,12 @@ solana-logger = { workspace = true }
solana-perf = { path = ".", features = ["dev-context-only-utils"] }
test-case = { workspace = true }
-[features]
-dev-context-only-utils = [
- "dep:solana-clock",
- "dep:solana-keypair",
- "dep:solana-signer",
- "dep:solana-system-interface",
- "dep:solana-system-transaction",
- "dep:solana-transaction",
- "dep:solana-vote-program",
- "dep:solana-vote",
-]
-frozen-abi = [
- "dep:solana-frozen-abi",
- "dep:solana-frozen-abi-macro",
- "solana-short-vec/frozen-abi",
- "solana-vote-program/frozen-abi",
-]
-
[[bench]]
name = "sigverify"
[[bench]]
name = "discard"
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ['cfg(build_target_feature_avx)', 'cfg(build_target_feature_avx2)']
diff --git a/platform-tools-sdk/cargo-build-sbf/Cargo.toml b/platform-tools-sdk/cargo-build-sbf/Cargo.toml
index 8c6ed2d2024bc7..e4b3c84bc8d9ec 100644
--- a/platform-tools-sdk/cargo-build-sbf/Cargo.toml
+++ b/platform-tools-sdk/cargo-build-sbf/Cargo.toml
@@ -9,6 +9,13 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[[bin]]
+name = "cargo-build-sbf"
+path = "src/main.rs"
+
+[features]
+program = []
+
[dependencies]
bzip2 = { workspace = true }
cargo_metadata = { workspace = true }
@@ -27,10 +34,3 @@ tar = { workspace = true }
assert_cmd = { workspace = true }
predicates = { workspace = true }
serial_test = { workspace = true }
-
-[features]
-program = []
-
-[[bin]]
-name = "cargo-build-sbf"
-path = "src/main.rs"
diff --git a/platform-tools-sdk/cargo-build-sbf/src/main.rs b/platform-tools-sdk/cargo-build-sbf/src/main.rs
index 651b9c1334aba4..979bac43e362fa 100644
--- a/platform-tools-sdk/cargo-build-sbf/src/main.rs
+++ b/platform-tools-sdk/cargo-build-sbf/src/main.rs
@@ -47,6 +47,7 @@ pub struct Config<'a> {
jobs: Option,
arch: &'a str,
optimize_size: bool,
+ lto: bool,
}
impl Default for Config<'_> {
@@ -78,6 +79,7 @@ impl Default for Config<'_> {
jobs: None,
arch: "v0",
optimize_size: false,
+ lto: false,
}
}
}
@@ -553,6 +555,12 @@ fn invoke_cargo(config: &Config) {
if config.optimize_size {
target_rustflags = Cow::Owned(format!("{} -C opt-level=s", &target_rustflags));
}
+ if config.lto {
+ target_rustflags = Cow::Owned(format!(
+ "{} -C embed-bitcode=yes -C lto=fat",
+ &target_rustflags
+ ));
+ }
if config.debug {
// Replace with -Zsplit-debuginfo=packed when stabilized.
target_rustflags = Cow::Owned(format!("{} -g", &target_rustflags));
@@ -878,6 +886,14 @@ fn main() {
.takes_value(false)
.help("Optimize program for size. This option may reduce program size, potentially increasing CU consumption.")
)
+ .arg(
+ Arg::new("lto")
+ .long("lto")
+ .takes_value(false)
+ .help("Enable Link-Time Optimization (LTO) for all crates being built. \
+ This option may decrease program size and CU consumption. The default option is LTO \
+ disabled, as one may get mixed results with it.")
+ )
.get_matches_from(args);
let sbf_sdk: PathBuf = matches.value_of_t_or_exit("sbf_sdk");
@@ -948,6 +964,7 @@ fn main() {
jobs: matches.value_of_t("jobs").ok(),
arch: matches.value_of("arch").unwrap(),
optimize_size: matches.is_present("optimize_size"),
+ lto: matches.is_present("lto"),
};
let manifest_path: Option = matches.value_of_t("manifest_path").ok();
if config.verbose {
diff --git a/platform-tools-sdk/cargo-build-sbf/tests/crates.rs b/platform-tools-sdk/cargo-build-sbf/tests/crates.rs
index 469321c3dd54aa..7ccf3f4fec0f8f 100644
--- a/platform-tools-sdk/cargo-build-sbf/tests/crates.rs
+++ b/platform-tools-sdk/cargo-build-sbf/tests/crates.rs
@@ -97,7 +97,7 @@ fn test_out_dir() {
#[serial]
fn test_target_dir() {
let target_dir = "./temp-target-dir";
- run_cargo_build("noop", &["--", "--target-dir", target_dir], false);
+ run_cargo_build("noop", &["--lto", "--", "--target-dir", target_dir], false);
let cwd = env::current_dir().expect("Unable to get current working directory");
let normal_target_dir = cwd.join("tests").join("crates").join("noop").join("target");
assert!(!normal_target_dir.exists());
diff --git a/platform-tools-sdk/cargo-build-sbf/tests/crates/fail/Cargo.toml b/platform-tools-sdk/cargo-build-sbf/tests/crates/fail/Cargo.toml
index 633b7f1fd18949..43be8bcdac4b0d 100644
--- a/platform-tools-sdk/cargo-build-sbf/tests/crates/fail/Cargo.toml
+++ b/platform-tools-sdk/cargo-build-sbf/tests/crates/fail/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "fail"
-version = "2.3.0"
+version = "3.0.0"
description = "Solana SBF test program written in Rust"
authors = ["Anza Maintainers "]
repository = "https://github.com/anza-xyz/agave"
@@ -10,10 +10,10 @@ edition = "2021"
publish = false
[dependencies]
-solana-account-info = "=2.2.0"
-solana-program-entrypoint = "=2.2.0"
-solana-program-error = "=2.2.0"
-solana-pubkey = "=2.2.0"
+solana-account-info = "=2.3.0"
+solana-program-entrypoint = "=2.2.1"
+solana-program-error = "=2.2.2"
+solana-pubkey = "=2.4.0"
[lib]
crate-type = ["cdylib"]
diff --git a/platform-tools-sdk/cargo-build-sbf/tests/crates/noop/Cargo.toml b/platform-tools-sdk/cargo-build-sbf/tests/crates/noop/Cargo.toml
index 384901d0305f21..fe40eb10d8f2e1 100644
--- a/platform-tools-sdk/cargo-build-sbf/tests/crates/noop/Cargo.toml
+++ b/platform-tools-sdk/cargo-build-sbf/tests/crates/noop/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "noop"
-version = "2.3.0"
+version = "3.0.0"
description = "Solana SBF test program written in Rust"
authors = ["Anza Maintainers "]
repository = "https://github.com/anza-xyz/agave"
@@ -10,10 +10,10 @@ edition = "2021"
publish = false
[dependencies]
-solana-account-info = "=2.2.0"
-solana-program-entrypoint = "=2.2.0"
-solana-program-error = "=2.2.0"
-solana-pubkey = "=2.2.0"
+solana-account-info = "=2.3.0"
+solana-program-entrypoint = "=2.2.1"
+solana-program-error = "=2.2.2"
+solana-pubkey = "=2.4.0"
[lib]
crate-type = ["cdylib"]
diff --git a/platform-tools-sdk/cargo-build-sbf/tests/crates/package-metadata/Cargo.toml b/platform-tools-sdk/cargo-build-sbf/tests/crates/package-metadata/Cargo.toml
index 8df6293e8cf121..d3bfe3ab5518e7 100644
--- a/platform-tools-sdk/cargo-build-sbf/tests/crates/package-metadata/Cargo.toml
+++ b/platform-tools-sdk/cargo-build-sbf/tests/crates/package-metadata/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "package-metadata"
-version = "2.3.0"
+version = "3.0.0"
description = "Solana SBF test program with tools version in package metadata"
authors = ["Anza Maintainers "]
repository = "https://github.com/anza-xyz/agave"
@@ -14,11 +14,11 @@ tools-version = "v1.48"
program-id = "MyProgram1111111111111111111111111111111111"
[dependencies]
-solana-account-info = "=2.2.0"
-solana-package-metadata = "=2.2.0"
-solana-program-entrypoint = "=2.2.0"
-solana-program-error = "=2.2.0"
-solana-pubkey = "=2.2.0"
+solana-account-info = "=2.3.0"
+solana-package-metadata = "=2.2.1"
+solana-program-entrypoint = "=2.2.1"
+solana-program-error = "=2.2.2"
+solana-pubkey = "=2.4.0"
[lib]
crate-type = ["cdylib"]
diff --git a/platform-tools-sdk/cargo-build-sbf/tests/crates/workspace-metadata/Cargo.toml b/platform-tools-sdk/cargo-build-sbf/tests/crates/workspace-metadata/Cargo.toml
index e0fc469494bba5..755dd6e8856f36 100644
--- a/platform-tools-sdk/cargo-build-sbf/tests/crates/workspace-metadata/Cargo.toml
+++ b/platform-tools-sdk/cargo-build-sbf/tests/crates/workspace-metadata/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "workspace-metadata"
-version = "2.3.0"
+version = "3.0.0"
description = "Solana SBF test program with tools version in workspace metadata"
authors = ["Anza Maintainers "]
repository = "https://github.com/anza-xyz/agave"
@@ -10,10 +10,10 @@ edition = "2021"
publish = false
[dependencies]
-solana-account-info = "=2.2.0"
-solana-program-entrypoint = "=2.2.0"
-solana-program-error = "=2.2.0"
-solana-pubkey = "=2.2.0"
+solana-account-info = "=2.3.0"
+solana-program-entrypoint = "=2.2.1"
+solana-program-error = "=2.2.2"
+solana-pubkey = "=2.4.0"
[lib]
crate-type = ["cdylib"]
diff --git a/platform-tools-sdk/cargo-test-sbf/Cargo.toml b/platform-tools-sdk/cargo-test-sbf/Cargo.toml
index 80594997613f00..fa0fb2fe2cbc7c 100644
--- a/platform-tools-sdk/cargo-test-sbf/Cargo.toml
+++ b/platform-tools-sdk/cargo-test-sbf/Cargo.toml
@@ -9,6 +9,10 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[[bin]]
+name = "cargo-test-sbf"
+path = "src/main.rs"
+
[dependencies]
cargo_metadata = { workspace = true }
clap = { version = "3.1.5", features = ["cargo"] }
@@ -16,7 +20,3 @@ itertools = { workspace = true }
log = { workspace = true, features = ["std"] }
regex = { workspace = true }
solana-logger = "=2.3.1"
-
-[[bin]]
-name = "cargo-test-sbf"
-path = "src/main.rs"
diff --git a/platform-tools-sdk/gen-headers/Cargo.toml b/platform-tools-sdk/gen-headers/Cargo.toml
index 588bb11ee57c6d..35327f604fb828 100644
--- a/platform-tools-sdk/gen-headers/Cargo.toml
+++ b/platform-tools-sdk/gen-headers/Cargo.toml
@@ -8,10 +8,10 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
-[dependencies]
-log = { workspace = true, features = ["std"] }
-regex = { workspace = true }
-
[[bin]]
name = "gen-headers"
path = "src/main.rs"
+
+[dependencies]
+log = { workspace = true, features = ["std"] }
+regex = { workspace = true }
diff --git a/poh-bench/Cargo.toml b/poh-bench/Cargo.toml
index 77df7970107b91..e95e7a22a02cb4 100644
--- a/poh-bench/Cargo.toml
+++ b/poh-bench/Cargo.toml
@@ -9,6 +9,9 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
[dependencies]
clap = { version = "3.1.5", features = ["cargo"] }
log = { workspace = true }
@@ -20,6 +23,3 @@ solana-perf = { workspace = true }
solana-rayon-threadlimit = { workspace = true }
solana-sha256-hasher = { workspace = true }
solana-version = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
diff --git a/poh/Cargo.toml b/poh/Cargo.toml
index ccffcdcdeec326..96abb25ac66a3e 100644
--- a/poh/Cargo.toml
+++ b/poh/Cargo.toml
@@ -9,6 +9,16 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+crate-type = ["lib"]
+name = "solana_poh"
+
+[features]
+dev-context-only-utils = []
+
[dependencies]
core_affinity = { workspace = true }
crossbeam-channel = { workspace = true }
@@ -30,6 +40,7 @@ thiserror = { workspace = true }
[dev-dependencies]
assert_matches = { workspace = true }
bincode = { workspace = true }
+criterion = { workspace = true }
rand = { workspace = true }
solana-keypair = { workspace = true }
solana-logger = { workspace = true }
@@ -40,15 +51,9 @@ solana-sha256-hasher = { workspace = true }
solana-signer = { workspace = true }
solana-system-transaction = { workspace = true }
-[features]
-dev-context-only-utils = []
-
-[lib]
-crate-type = ["lib"]
-name = "solana_poh"
-
[[bench]]
name = "poh"
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
+[[bench]]
+name = "transaction_recorder"
+harness = false
diff --git a/poh/benches/poh.rs b/poh/benches/poh.rs
index 5cbc4c164e4ca0..b12ac32ae8ab3b 100644
--- a/poh/benches/poh.rs
+++ b/poh/benches/poh.rs
@@ -111,15 +111,13 @@ fn bench_poh_recorder_record_transaction_index(bencher: &mut Bencher) {
SanitizedTransaction::from_transaction_for_tests(test_tx()),
];
+ let txs: Vec<_> = txs.iter().map(|tx| tx.to_versioned_transaction()).collect();
bencher.iter(|| {
let _record_result = poh_recorder
.record(
bank.slot(),
- test::black_box(h1),
- test::black_box(&txs)
- .iter()
- .map(|tx| tx.to_versioned_transaction())
- .collect(),
+ vec![test::black_box(h1)],
+ vec![test::black_box(txs.clone())],
)
.unwrap()
.unwrap();
diff --git a/poh/benches/transaction_recorder.rs b/poh/benches/transaction_recorder.rs
new file mode 100644
index 00000000000000..0b7d8e3489d8dc
--- /dev/null
+++ b/poh/benches/transaction_recorder.rs
@@ -0,0 +1,129 @@
+use {
+ criterion::{criterion_group, criterion_main, Criterion},
+ solana_hash::Hash,
+ solana_keypair::Keypair,
+ solana_ledger::{
+ blockstore::Blockstore, genesis_utils::create_genesis_config,
+ get_tmp_ledger_path_auto_delete, leader_schedule_cache::LeaderScheduleCache,
+ },
+ solana_poh::{
+ poh_recorder::PohRecorder,
+ poh_service::{PohService, DEFAULT_HASHES_PER_BATCH, DEFAULT_PINNED_CPU_CORE},
+ transaction_recorder::TransactionRecorder,
+ },
+ solana_poh_config::PohConfig,
+ solana_pubkey::Pubkey,
+ solana_runtime::{bank::Bank, installed_scheduler_pool::BankWithScheduler},
+ solana_transaction::versioned::VersionedTransaction,
+ std::{
+ sync::{atomic::AtomicBool, Arc, RwLock},
+ time::{Duration, Instant},
+ },
+};
+
+fn bench_record_transactions(c: &mut Criterion) {
+ // Relatively small non-zero number of transactions to use for the benchmark.
+ // Ensures we spend some time doing the hash work for entry recording.
+ const NUM_TRANSACTIONS: u64 = 16;
+ // Number of batches to process in each benchmark iteration.
+ // Each batch contains NUM_TRANSACTIONS transactions.
+ // This emulates a burst of work coming in from the scheduler.
+ const NUM_BATCHES: u64 = 32;
+
+ // Setup the PohService.
+ let mut genesis_config_info = create_genesis_config(2);
+ genesis_config_info.genesis_config.ticks_per_slot = solana_clock::DEFAULT_TICKS_PER_SLOT;
+ genesis_config_info.genesis_config.poh_config = PohConfig {
+ target_tick_duration: Duration::from_micros(
+ solana_clock::DEFAULT_MS_PER_SLOT * 1_000 / solana_clock::DEFAULT_TICKS_PER_SLOT,
+ ),
+ target_tick_count: None,
+ hashes_per_tick: Some(solana_clock::DEFAULT_HASHES_PER_TICK),
+ };
+ let exit = Arc::new(AtomicBool::new(false));
+ let mut bank = Arc::new(Bank::new_for_tests(&genesis_config_info.genesis_config));
+ let ledger_path = get_tmp_ledger_path_auto_delete!();
+ let blockstore = Arc::new(
+ Blockstore::open(ledger_path.path()).expect("Expected to be able to open database ledger"),
+ );
+ let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
+ bank.tick_height(),
+ bank.last_blockhash(),
+ bank.clone(),
+ None,
+ bank.ticks_per_slot(),
+ blockstore,
+ &Arc::new(LeaderScheduleCache::new_from_bank(&bank)),
+ &genesis_config_info.genesis_config.poh_config,
+ exit.clone(),
+ );
+ poh_recorder.set_bank(
+ BankWithScheduler::new_without_scheduler(bank.clone()),
+ false,
+ );
+
+ let (record_sender, record_receiver) = crossbeam_channel::unbounded();
+ let transaction_recorder = TransactionRecorder::new(record_sender, exit.clone());
+
+ let txs: Vec<_> = (0..NUM_TRANSACTIONS)
+ .map(|_| {
+ VersionedTransaction::from(solana_system_transaction::transfer(
+ &Keypair::new(),
+ &Pubkey::new_unique(),
+ 1,
+ Hash::new_unique(),
+ ))
+ })
+ .collect();
+
+ let poh_recorder = Arc::new(RwLock::new(poh_recorder));
+ let poh_service = PohService::new(
+ poh_recorder.clone(),
+ &genesis_config_info.genesis_config.poh_config,
+ exit.clone(),
+ bank.ticks_per_slot(),
+ DEFAULT_PINNED_CPU_CORE,
+ DEFAULT_HASHES_PER_BATCH,
+ record_receiver,
+ );
+
+ let mut group = c.benchmark_group("record_transactions");
+ group.throughput(criterion::Throughput::Elements(
+ NUM_TRANSACTIONS * NUM_BATCHES,
+ ));
+ group.bench_function("record_transactions", |b| {
+ b.iter_custom(|iters| {
+ let mut total = Duration::ZERO;
+
+ for _ in 0..iters {
+ let tx_batches: Vec<_> = (0..NUM_BATCHES).map(|_| txs.clone()).collect();
+ poh_recorder.write().unwrap().clear_bank_for_test();
+ bank = Arc::new(Bank::new_from_parent(
+ bank.clone(),
+ &Pubkey::default(),
+ bank.slot().wrapping_add(1),
+ ));
+ poh_recorder.write().unwrap().set_bank(
+ BankWithScheduler::new_without_scheduler(bank.clone()),
+ false,
+ );
+
+ let start = Instant::now();
+ for txs in tx_batches {
+ let summary = transaction_recorder.record_transactions(bank.slot(), txs);
+ assert!(summary.result.is_ok());
+ }
+ let elapsed = start.elapsed();
+ total = total.saturating_add(elapsed);
+ }
+
+ total
+ })
+ });
+
+ exit.store(true, std::sync::atomic::Ordering::Relaxed);
+ poh_service.join().unwrap();
+}
+
+criterion_group!(benches, bench_record_transactions,);
+criterion_main!(benches);
diff --git a/poh/src/poh_recorder.rs b/poh/src/poh_recorder.rs
index 99e648ec005d3b..cb9f3da5817291 100644
--- a/poh/src/poh_recorder.rs
+++ b/poh/src/poh_recorder.rs
@@ -20,7 +20,10 @@ use {
crossbeam_channel::{unbounded, Receiver, SendError, Sender, TrySendError},
log::*,
solana_clock::{Slot, NUM_CONSECUTIVE_LEADER_SLOTS},
- solana_entry::{entry::Entry, poh::Poh},
+ solana_entry::{
+ entry::Entry,
+ poh::{Poh, PohEntry},
+ },
solana_hash::Hash,
solana_ledger::{blockstore::Blockstore, leader_schedule_cache::LeaderScheduleCache},
solana_measure::measure_us,
@@ -75,21 +78,21 @@ impl BankStart {
type RecordResultSender = Sender>>;
pub struct Record {
- pub mixin: Hash,
- pub transactions: Vec,
+ pub mixins: Vec,
+ pub transaction_batches: Vec>,
pub slot: Slot,
pub sender: RecordResultSender,
}
impl Record {
pub fn new(
- mixin: Hash,
- transactions: Vec,
+ mixins: Vec,
+ transaction_batches: Vec>,
slot: Slot,
sender: RecordResultSender,
) -> Self {
Self {
- mixin,
- transactions,
+ mixins,
+ transaction_batches,
slot,
sender,
}
@@ -188,6 +191,9 @@ pub struct PohRecorder {
delay_leader_block_for_pending_fork: bool,
last_reported_slot_for_pending_fork: Arc>,
pub is_exited: Arc,
+
+ // Allocation to hold PohEntrys recorded into PoHStream.
+ entries: Vec,
}
impl PohRecorder {
@@ -272,6 +278,7 @@ impl PohRecorder {
delay_leader_block_for_pending_fork,
last_reported_slot_for_pending_fork: Arc::default(),
is_exited,
+ entries: Vec::with_capacity(64),
},
working_bank_receiver,
)
@@ -294,12 +301,19 @@ impl PohRecorder {
pub(crate) fn record(
&mut self,
bank_slot: Slot,
- mixin: Hash,
- transactions: Vec,
+ mixins: Vec,
+ transaction_batches: Vec>,
) -> Result