Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions core/src/bam_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,13 @@ impl BamManager {
.store(BamConnectionState::Connected as u8, Ordering::Release);
}
}
// Send leader state if we are in a leader slot
if let Some(bank) = shared_leader_state.load().working_bank()
// Bank and readiness from one snapshot; a same-slot replacement must not mix them.
let state = shared_leader_state.load();
if let Some(bank) = state.working_bank()
&& !bank.is_frozen()
{
let leader_state = Self::generate_leader_state(bank);
let leader_state =
Self::generate_leader_state(bank, state.atomic_batches_enabled());
let _ = dependencies
.outbound_sender
.try_send(BamOutboundMessage::LeaderState(leader_state));
Expand Down Expand Up @@ -332,7 +334,7 @@ impl BamManager {
true
}

fn generate_leader_state(bank: &Bank) -> LeaderState {
fn generate_leader_state(bank: &Bank, atomic_batches_enabled: bool) -> LeaderState {
let cost_tracker = bank.read_cost_tracker().unwrap();
let max_block_cu = cost_tracker.block_cost_limit();
let consumed_block_cu = cost_tracker.block_cost();
Expand All @@ -342,6 +344,9 @@ impl BamManager {
slot: bank.slot(),
tick: (bank.tick_height() % bank.ticks_per_slot()) as u32,
slot_cu_budget_remaining,

@buffalu buffalu Sep 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we need to add the current bank id here too? i need to read into AG more, but think we need to target the bank slot/bank id when were sending the atomic tx batches so that our speculative bank is built properly

parent_slot: Some(bank.parent_slot()),
parent_block_id: bank.parent_block_id().map(|id| id.to_bytes().to_vec()),
atomic_batches_enabled: Some(atomic_batches_enabled),
}
}

Expand Down Expand Up @@ -557,3 +562,32 @@ impl BamManager {
self.thread.join()
}
}

#[cfg(test)]
mod tests {
use {
super::*, solana_hash::Hash, solana_leader_schedule::SlotLeader,
solana_runtime::genesis_utils::create_genesis_config,
};

#[test]
fn leader_state_carries_parent_identity_and_readiness() {
let genesis = create_genesis_config(1_000_000_000);
let (parent, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis.genesis_config);
let parent_block_id = Hash::new_unique();
parent.set_block_id(Some(parent_block_id));
let bank = Bank::new_from_parent(parent.clone(), SlotLeader::new_unique(), 7);

let state = BamManager::generate_leader_state(&bank, true);
assert_eq!(state.slot, 7);
assert_eq!(state.parent_slot, Some(parent.slot()));
assert_eq!(
state.parent_block_id.as_deref(),
Some(parent_block_id.as_ref())
);
assert_eq!(state.atomic_batches_enabled, Some(true));

let state = BamManager::generate_leader_state(&bank, false);
assert_eq!(state.atomic_batches_enabled, Some(false));
}
}
2 changes: 1 addition & 1 deletion jito-protos/bam-protos
Submodule bam-protos updated 1 files
+5 −0 bam_types.proto