From 950332e680b0ab5f2b610deedc1b3c04563f3222 Mon Sep 17 00:00:00 2001 From: taco-paco Date: Thu, 9 Jul 2026 13:02:36 +0700 Subject: [PATCH] refactor: mome LatestBlockInner into core to be able to expose subscribe method in LatestBlockProvider --- magicblock-aperture/src/geyser.rs | 4 +-- magicblock-aperture/src/processor.rs | 7 +++-- magicblock-aperture/src/state/blocks.rs | 6 ++-- magicblock-core/Cargo.toml | 4 +-- magicblock-core/src/link/blocks.rs | 24 +++++++++++++++ magicblock-core/src/traits.rs | 3 ++ .../src/blockstore_processor/mod.rs | 9 ++++-- magicblock-ledger/src/lib.rs | 30 +++++-------------- magicblock-ledger/src/store/api.rs | 4 +-- magicblock-ledger/tests/get_block.rs | 2 +- .../tests/test_ledger_truncator.rs | 5 ++-- magicblock-processor/src/executor/mod.rs | 3 +- magicblock-processor/src/scheduler/mod.rs | 3 +- test-kit/src/lib.rs | 3 +- 14 files changed, 63 insertions(+), 44 deletions(-) diff --git a/magicblock-aperture/src/geyser.rs b/magicblock-aperture/src/geyser.rs index 4e3bbf6fb..7fed97384 100644 --- a/magicblock-aperture/src/geyser.rs +++ b/magicblock-aperture/src/geyser.rs @@ -8,9 +8,9 @@ use agave_geyser_plugin_interface::geyser_plugin_interface::{ use json::{JsonValueTrait, Value}; use libloading::{Library, Symbol}; use magicblock_core::link::{ - accounts::AccountWithSlot, transactions::TransactionStatus, + accounts::AccountWithSlot, blocks::LatestBlockInner, + transactions::TransactionStatus, }; -use magicblock_ledger::LatestBlockInner; use solana_account::ReadableAccount; const ENTRYPOINT_SYMBOL: &[u8] = b"_create_plugin"; diff --git a/magicblock-aperture/src/processor.rs b/magicblock-aperture/src/processor.rs index 5005ad5c3..d50ca0d73 100644 --- a/magicblock-aperture/src/processor.rs +++ b/magicblock-aperture/src/processor.rs @@ -2,10 +2,11 @@ use std::sync::Arc; use magicblock_config::config::ApertureConfig; use magicblock_core::link::{ - accounts::AccountUpdateRx, blocks::BlockUpdateRx, - transactions::TransactionStatusRx, DispatchEndpoints, + accounts::AccountUpdateRx, + blocks::{BlockUpdateRx, LatestBlockInner}, + transactions::TransactionStatusRx, + DispatchEndpoints, }; -use magicblock_ledger::LatestBlockInner; use tokio_util::sync::CancellationToken; use tracing::{info, instrument, warn}; diff --git a/magicblock-aperture/src/state/blocks.rs b/magicblock-aperture/src/state/blocks.rs index 88c1b20c9..be55c68e8 100644 --- a/magicblock-aperture/src/state/blocks.rs +++ b/magicblock-aperture/src/state/blocks.rs @@ -1,8 +1,10 @@ use std::{ops::Deref, sync::Arc, time::Duration}; use arc_swap::ArcSwapAny; -use magicblock_core::{link::blocks::BlockHash, Slot}; -use magicblock_ledger::LatestBlockInner; +use magicblock_core::{ + link::blocks::{BlockHash, LatestBlockInner}, + Slot, +}; use solana_rpc_client_api::response::RpcBlockhash; use super::ExpiringCache; diff --git a/magicblock-core/Cargo.toml b/magicblock-core/Cargo.toml index fe621634b..e1cd89dff 100644 --- a/magicblock-core/Cargo.toml +++ b/magicblock-core/Cargo.toml @@ -17,7 +17,7 @@ bytes = { workspace = true } serde = { workspace = true, features = ["derive"] } solana-account = { workspace = true } -solana-account-decoder = { workspace = true } +solana-account-decoder = { workspace = true, features = ["agave-unstable-api"] } solana-clock = { workspace = true } solana-hash = { workspace = true } solana-message = { workspace = true } @@ -27,7 +27,7 @@ solana-signature = { workspace = true } solana-transaction = { workspace = true, features = ["blake3", "verify"] } solana-transaction-context = { workspace = true } solana-transaction-error = { workspace = true } -solana-transaction-status-client-types = { workspace = true } +solana-transaction-status-client-types = { workspace = true, features = ["agave-unstable-api"] } magicblock-magic-program-api = { workspace = true } spl-token = { workspace = true } spl-token-2022 = { workspace = true } diff --git a/magicblock-core/src/link/blocks.rs b/magicblock-core/src/link/blocks.rs index 559e16725..639c232c8 100644 --- a/magicblock-core/src/link/blocks.rs +++ b/magicblock-core/src/link/blocks.rs @@ -1,3 +1,4 @@ +use solana_clock::Clock; use solana_hash::Hash; use tokio::sync::broadcast; @@ -8,3 +9,26 @@ pub type BlockHash = Hash; /// Typically instantiated as `BlockUpdateRx` where the payload /// contains the latest block data (slot, blockhash, timestamp). pub type BlockUpdateRx = broadcast::Receiver; + +#[derive(Default, Clone)] +pub struct LatestBlockInner { + pub slot: u64, + pub blockhash: BlockHash, + pub clock: Clock, +} + +impl LatestBlockInner { + pub fn new(slot: u64, blockhash: BlockHash, timestamp: i64) -> Self { + let clock = Clock { + slot: slot + 1, + unix_timestamp: timestamp, + ..Default::default() + }; + + Self { + slot, + blockhash, + clock, + } + } +} diff --git a/magicblock-core/src/traits.rs b/magicblock-core/src/traits.rs index 7ccc27bae..6937030de 100644 --- a/magicblock-core/src/traits.rs +++ b/magicblock-core/src/traits.rs @@ -6,9 +6,11 @@ use solana_program::instruction::InstructionError; use solana_pubkey::Pubkey; use solana_signature::Signature; use solana_transaction_error::TransactionError; +use tokio::sync::broadcast; use crate::{ intent::{BaseActionCallback, CommittedAccount}, + link::blocks::LatestBlockInner, Slot, }; @@ -28,6 +30,7 @@ pub trait LatestBlockProvider: Send + Sync + Clone + 'static { fn slot(&self) -> Slot; fn blockhash(&self) -> Hash; fn clock(&self) -> Clock; + fn subscribe(&self) -> broadcast::Receiver; } /// Interface for service handling callback execution/scheduling diff --git a/magicblock-ledger/src/blockstore_processor/mod.rs b/magicblock-ledger/src/blockstore_processor/mod.rs index 9e60bf1a4..6528b1cec 100644 --- a/magicblock-ledger/src/blockstore_processor/mod.rs +++ b/magicblock-ledger/src/blockstore_processor/mod.rs @@ -1,7 +1,10 @@ use std::str::FromStr; -use magicblock_core::link::transactions::{ - ReplayPosition, SanitizeableTransaction, TransactionSchedulerHandle, +use magicblock_core::link::{ + blocks::LatestBlockInner, + transactions::{ + ReplayPosition, SanitizeableTransaction, TransactionSchedulerHandle, + }, }; use num_format::{Locale, ToFormattedString}; use solana_clock::{Slot, UnixTimestamp}; @@ -12,7 +15,7 @@ use tracing::{Level, *}; use crate::{ errors::{LedgerError, LedgerResult}, - LatestBlockInner, Ledger, + Ledger, }; #[derive(Debug)] diff --git a/magicblock-ledger/src/lib.rs b/magicblock-ledger/src/lib.rs index 77b9e4210..359d6b30a 100644 --- a/magicblock-ledger/src/lib.rs +++ b/magicblock-ledger/src/lib.rs @@ -5,19 +5,14 @@ pub use database::{ meta::PerfSample, options::{LedgerOptions, BLOCKSTORE_DIRECTORY_ROCKS_LEVEL}, }; -use magicblock_core::traits::LatestBlockProvider; +use magicblock_core::{ + link::blocks::LatestBlockInner, traits::LatestBlockProvider, +}; use solana_clock::Clock; use solana_hash::Hash; pub use store::api::{Ledger, SignatureInfosForAddress}; use tokio::sync::broadcast; -#[derive(Default, Clone)] -pub struct LatestBlockInner { - pub slot: u64, - pub blockhash: Hash, - pub clock: Clock, -} - /// Atomically updated, shared, latest block information /// The instances of this type can be used by various components /// of the validator to cheaply retrieve the latest block data, @@ -35,21 +30,6 @@ pub struct LatestBlock { notifier: broadcast::Sender, } -impl LatestBlockInner { - pub fn new(slot: u64, blockhash: Hash, timestamp: i64) -> Self { - let clock = Clock { - slot: slot + 1, - unix_timestamp: timestamp, - ..Default::default() - }; - Self { - slot, - blockhash, - clock, - } - } -} - impl Default for LatestBlock { fn default() -> Self { let (notifier, _) = broadcast::channel(32); @@ -93,6 +73,10 @@ impl LatestBlockProvider for LatestBlock { fn clock(&self) -> Clock { self.inner.load().clock.clone() } + + fn subscribe(&self) -> broadcast::Receiver { + self.subscribe() + } } pub mod blockstore_processor; diff --git a/magicblock-ledger/src/store/api.rs b/magicblock-ledger/src/store/api.rs index 49dd36285..2501b28e5 100644 --- a/magicblock-ledger/src/store/api.rs +++ b/magicblock-ledger/src/store/api.rs @@ -9,7 +9,7 @@ use std::{ }; use bincode::{deserialize, serialize}; -use magicblock_core::link::blocks::BlockHash; +use magicblock_core::link::blocks::{BlockHash, LatestBlockInner}; use magicblock_metrics::metrics::{ start_ledger_disable_compactions_timer, start_ledger_shutdown_timer, HistogramTimer, @@ -42,7 +42,7 @@ use crate::{ errors::{LedgerError, LedgerResult}, metrics::LedgerRpcApiMetrics, store::utils::adjust_ulimit_nofile, - LatestBlock, LatestBlockInner, + LatestBlock, }; #[derive(Default, Debug)] diff --git a/magicblock-ledger/tests/get_block.rs b/magicblock-ledger/tests/get_block.rs index 7fa743c3b..0ce670942 100644 --- a/magicblock-ledger/tests/get_block.rs +++ b/magicblock-ledger/tests/get_block.rs @@ -1,6 +1,6 @@ mod common; -use magicblock_ledger::LatestBlockInner; +use magicblock_core::link::blocks::LatestBlockInner; use solana_hash::Hash; use test_kit::init_logger; diff --git a/magicblock-ledger/tests/test_ledger_truncator.rs b/magicblock-ledger/tests/test_ledger_truncator.rs index bec691149..c9cf440a3 100644 --- a/magicblock-ledger/tests/test_ledger_truncator.rs +++ b/magicblock-ledger/tests/test_ledger_truncator.rs @@ -1,9 +1,8 @@ mod common; use std::{sync::Arc, time::Duration}; -use magicblock_ledger::{ - ledger_truncator::LedgerTruncator, LatestBlockInner, Ledger, -}; +use magicblock_core::link::blocks::LatestBlockInner; +use magicblock_ledger::{ledger_truncator::LedgerTruncator, Ledger}; use solana_hash::Hash; use solana_signature::Signature; use test_kit::init_logger; diff --git a/magicblock-processor/src/executor/mod.rs b/magicblock-processor/src/executor/mod.rs index 0a2edab46..610240046 100644 --- a/magicblock-processor/src/executor/mod.rs +++ b/magicblock-processor/src/executor/mod.rs @@ -9,6 +9,7 @@ use magicblock_accounts_db::AccountsDb; use magicblock_core::{ link::{ accounts::AccountUpdateTx, + blocks::LatestBlockInner, transactions::{ ProcessableTransaction, ScheduledTasksTx, TransactionProcessingMode, TransactionStatusTx, @@ -16,7 +17,7 @@ use magicblock_core::{ }, Slot, }; -use magicblock_ledger::{LatestBlock, LatestBlockInner, Ledger}; +use magicblock_ledger::{LatestBlock, Ledger}; use solana_feature_set::FeatureSet; use solana_program::slot_hashes::SlotHashes; use solana_program_runtime::loaded_programs::{ diff --git a/magicblock-processor/src/scheduler/mod.rs b/magicblock-processor/src/scheduler/mod.rs index 30f294325..b2d8c2115 100644 --- a/magicblock-processor/src/scheduler/mod.rs +++ b/magicblock-processor/src/scheduler/mod.rs @@ -56,6 +56,7 @@ use locks::{ExecutorId, MAX_SVM_EXECUTORS}; use magicblock_accounts_db::{traits::AccountsBank, AccountsDb}; use magicblock_core::{ link::{ + blocks::LatestBlockInner, replication::{self, Message, SuperBlock}, transactions::{ ProcessableTransaction, SchedulerCommand, SchedulerCommandResult, @@ -64,7 +65,7 @@ use magicblock_core::{ }, Slot, }; -use magicblock_ledger::{LatestBlock, LatestBlockInner, Ledger}; +use magicblock_ledger::{LatestBlock, Ledger}; use magicblock_metrics::metrics; use solana_account::{from_account, to_account}; use solana_program::{clock::Clock, hash::Hash, slot_hashes::SlotHashes}; diff --git a/test-kit/src/lib.rs b/test-kit/src/lib.rs index 4f118c2e5..ed4f907dd 100644 --- a/test-kit/src/lib.rs +++ b/test-kit/src/lib.rs @@ -12,6 +12,7 @@ pub use guinea; use magicblock_accounts_db::{traits::AccountsBank, AccountsDb}; use magicblock_core::{ link::{ + blocks::LatestBlockInner, link, transactions::{ ReplayPosition, SanitizeableTransaction, SchedulerMode, @@ -21,7 +22,7 @@ use magicblock_core::{ }, Slot, }; -use magicblock_ledger::{LatestBlockInner, Ledger}; +use magicblock_ledger::Ledger; use magicblock_processor::{ build_svm_env, loader::load_upgradeable_programs,