Skip to content

Bank::get_slot_history() is fallible#12598

Merged
brooksprumo merged 1 commit into
anza-xyz:masterfrom
brooksprumo:get_slot_history
May 20, 2026
Merged

Bank::get_slot_history() is fallible#12598
brooksprumo merged 1 commit into
anza-xyz:masterfrom
brooksprumo:get_slot_history

Conversation

@brooksprumo
Copy link
Copy Markdown

Problem

Bank::get_slot_history() double unwraps, which causes a panic on error. Instead, let the caller decide if this error is fatal or not.

Summary of Changes

  • Makes Bank::get_slot_history() return an Option
  • Updates callers to call .unwrap() (this maintains the current behavior--happy to adjust!)
  • Add a new RPC error

@brooksprumo brooksprumo self-assigned this May 19, 2026
@mergify
Copy link
Copy Markdown

mergify Bot commented May 19, 2026

If this PR represents a change to the public RPC API:

  1. Make sure it includes a complementary update to rpc-client/ (example)
  2. Open a follow-up PR to update the JavaScript client @solana/kit (example)

Thank you for keeping the RPC clients in sync with the server API @brooksprumo.

Comment on lines +530 to +532
let slot_history = bank
.get_slot_history()
.expect("snapshot bank must have slot history");
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're at startup here, and slot history must exist. So get_slot_history() must succeed.

If preferred, we could add an error case on VerifySlotDeltasError instead.

Comment thread core/src/replay_stage.rs Outdated
let tower = Tower::restore(tower_storage, node_pubkey).and_then(|restored_tower| {
let root_bank = bank_forks.read().unwrap().root_bank();
let slot_history = root_bank.get_slot_history();
let slot_history = root_bank.get_slot_history().unwrap();
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this unwrap, or do something else?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imagine if root banks were their own type and you didn't have to ask because we wouldn't have successfully constructed one without this account existing


at least expect(). somehow stuffing this condition into all of these error types seems more wrong than panicking the validator

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's fine to expect here, the root advancing /snapshot happens via replay_stage so we don't have the same race

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've changed to expect() in fefb08c.

Comment thread core/src/validator.rs Outdated
let restored_tower = restored_tower.and_then(|tower| {
let root_bank = bank_forks.root_bank();
let slot_history = root_bank.get_slot_history();
let slot_history = root_bank.get_slot_history().unwrap();
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Should this unwrap, or do something else?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to unwrap/expect this code executes before the TVU (and replay stage) are started up, so the race is not present

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've changed to expect() in fefb08c.

@brooksprumo brooksprumo marked this pull request as ready for review May 19, 2026 17:49
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 19, 2026

Codecov Report

❌ Patch coverage is 52.63158% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.4%. Comparing base (90ffece) to head (fefb08c).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##           master   #12598     +/-   ##
=========================================
- Coverage    83.4%    83.4%   -0.1%     
=========================================
  Files         859      859             
  Lines      330742   330751      +9     
=========================================
- Hits       276057   276016     -41     
- Misses      54685    54735     +50     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

AshwinSekar
AshwinSekar previously approved these changes May 19, 2026
Comment thread core/src/replay_stage.rs Outdated
let tower = Tower::restore(tower_storage, node_pubkey).and_then(|restored_tower| {
let root_bank = bank_forks.read().unwrap().root_bank();
let slot_history = root_bank.get_slot_history();
let slot_history = root_bank.get_slot_history().unwrap();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's fine to expect here, the root advancing /snapshot happens via replay_stage so we don't have the same race

Comment thread core/src/validator.rs Outdated
let restored_tower = restored_tower.and_then(|tower| {
let root_bank = bank_forks.root_bank();
let slot_history = root_bank.get_slot_history();
let slot_history = root_bank.get_slot_history().unwrap();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to unwrap/expect this code executes before the TVU (and replay stage) are started up, so the race is not present

@t-nelson
Copy link
Copy Markdown

:shipit:

@brooksprumo brooksprumo added this pull request to the merge queue May 20, 2026
Merged via the queue into anza-xyz:master with commit ddb592b May 20, 2026
48 checks passed
@brooksprumo brooksprumo deleted the get_slot_history branch May 20, 2026 11:07
@steviez steviez added the v4.1 Backport to v4.1 branch label May 20, 2026
@mergify
Copy link
Copy Markdown

mergify Bot commented May 20, 2026

Backports to release branches are to be avoided unless absolutely necessary for fixing bugs, security issues, and perf regressions. Changes intended for backport should be structured such that a minimum effective diff can be committed separately from any 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. Exceptions include CI/metrics changes, CLI improvements and documentation updates on a case by case basis.

@brooksprumo brooksprumo added the v4.0 Backport to v4.0 branch label May 20, 2026
brooksprumo added a commit that referenced this pull request May 20, 2026
Bank::get_slot_history() is fallible (#12598)

(cherry picked from commit ddb592b)

Co-authored-by: Brooks <brooks@anza.xyz>
t-nelson pushed a commit that referenced this pull request May 21, 2026
(cherry picked from commit ddb592b)

# Conflicts:
#	runtime/src/snapshot_bank_utils.rs
brooksprumo added a commit that referenced this pull request May 25, 2026
* Bank::get_slot_history() is fallible (#12598)

(cherry picked from commit ddb592b)

# Conflicts:
#	runtime/src/snapshot_bank_utils.rs

* resolves merge conflicts

---------

Co-authored-by: Brooks <brooks@anza.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v4.0 Backport to v4.0 branch v4.1 Backport to v4.1 branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants