Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
10 changes: 6 additions & 4 deletions Cargo.lock

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

26 changes: 18 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ paste = "1.0"
prometheus = "0.13.4"
# Keep in sync with `solana-storage-proto` codegen.

# TODO: Update to the merged version when ready

solana-transaction-context = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82", features = [
solana-transaction-context = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28", features = [
"dev-context-only-utils",
] }
solana-transaction-error = { version = "3.0" }
Expand Down Expand Up @@ -194,7 +195,9 @@ serde_json = "1.0"
serde_with = "3.16"
serial_test = "3.2"
sha3 = "0.10.8"
solana-account = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82" }
# TODO: Update to the merged version when ready

solana-account = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28" }
solana-account-decoder = { version = "4.0" }
solana-account-decoder-client-types = { version = "4.0" }
solana-account-info = { version = "3.1" }
Expand Down Expand Up @@ -246,7 +249,8 @@ solana-program = "3.0"
solana-program-error = { version = "3.0" }
solana-program-option = { version = "3.0" }
solana-program-pack = { version = "3.0" }
solana-program-runtime = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82" }
# TODO: Update to the merged version when ready
solana-program-runtime = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28" }
solana-pubkey = { version = "4.1" }
solana-pubsub-client = { version = "4.0" }
solana-rent = { version = "3.0" }
Expand All @@ -270,22 +274,28 @@ solana-system-program = { version = "=4.0.0", features = [
] }
solana-system-transaction = { version = "3.0" }
solana-sysvar = { version = "3.0" }
solana-sysvar-id = { version = "3.0" }
solana-timings = { package = "solana-svm-timings", version = "=4.0.0", features = [
"agave-unstable-api",
] }
solana-transaction = { version = "3.0" }

# TODO: Update to the merged version when ready
[workspace.dependencies.solana-svm]
features = ["dev-context-only-utils"]
git = "https://github.com/magicblock-labs/magicblock-svm.git"
rev = "b275f82"
rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28"

[patch.crates-io]
solana-account = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82" }
solana-program-runtime = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82" }
# TODO: Update to the merged version when ready
solana-account = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28" }
# TODO: Update to the merged version when ready
solana-program-runtime = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28" }
solana-storage-proto = { path = "storage-proto" }
solana-svm = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82" }
solana-transaction-context = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "b275f82" }
# TODO: Update to the merged version when ready
solana-svm = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28" }
# TODO: Update to the merged version when ready
solana-transaction-context = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "bccdeeb1e773352cf0afef2087f4e752efe69a28" }
# Fork is used to enable `disable_manual_compaction` usage
# Fork is based on commit d4e9e16 of rocksdb (parent commit of 0.23.0 release)
# without patching update isn't possible due to conflict with solana deps
Expand Down
4 changes: 4 additions & 0 deletions magicblock-core/src/link/replication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ pub struct Block {
pub hash: Hash,
/// Unix timestamp (seconds).
pub timestamp: i64,

@GabrielePicco GabrielePicco Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

timestamp is now redundant. We can remove it after a migration time (once all ledgers truncated all blocks with the legacy timestamp)

@GabrielePicco GabrielePicco Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would be great to document this and leave a TODO in the codebase to remove the timestamp

/// Sub-second component of the timestamp, in nanoseconds
/// (`[0, 1_000_000_000)`), preserving the precision discarded when
/// rounding down to whole seconds for `timestamp`.
pub nanos: u32,
}

/// Periodic checkpoint for state verification and catch-up.
Expand Down
13 changes: 10 additions & 3 deletions magicblock-ledger/src/blockstore_processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,16 @@ async fn replay_blocks(
)));
};
{
let block =
LatestBlockInner::new(block.slot, block.blockhash, timestamp);
ledger.latest_block().store(block);
// Restore the sub-second precision so the HighPrecisionClock sysvar
// is reproduced exactly during replay. Absent (0) for slots written
// before high-precision time was persisted.
let latest = LatestBlockInner::new_with_nanos(
block.slot,
block.blockhash,
timestamp,
ledger.get_block_time_nanos(block.slot)?.unwrap_or_default(),
);
ledger.latest_block().store(latest);
}
// Transactions are stored in the ledger ordered by most recent to latest
// such to replay them in the order they executed we need to reverse them
Expand Down
1 change: 1 addition & 0 deletions magicblock-ledger/src/database/cf_descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub fn cf_descriptors(
new_cf_descriptor::<AddressSignatures>(options, oldest_slot),
new_cf_descriptor::<SlotSignatures>(options, oldest_slot),
new_cf_descriptor::<Blocktime>(options, oldest_slot),
new_cf_descriptor::<BlocktimeNanos>(options, oldest_slot),
new_cf_descriptor::<Blockhash>(options, oldest_slot),
new_cf_descriptor::<Transaction>(options, oldest_slot),
new_cf_descriptor::<TransactionMemos>(options, oldest_slot),
Expand Down
25 changes: 25 additions & 0 deletions magicblock-ledger/src/database/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const ADDRESS_SIGNATURES_CF: &str = "address_signatures";
const SLOT_SIGNATURES_CF: &str = "slot_signatures";
/// Column family for Blocktime
const BLOCKTIME_CF: &str = "blocktime";
/// Column family for the sub-second (nanosecond) component of the block time
const BLOCKTIME_NANOS_CF: &str = "blocktime_nanos";
/// Column family for Blockhash
const BLOCKHASH_CF: &str = "blockhash";
/// Column family for Confirmed Transaction
Expand Down Expand Up @@ -60,6 +62,17 @@ pub struct SlotSignatures;
/// * value type: [`UnixTimestamp`]
pub struct Blocktime;

/// The sub-second component of the block time, in nanoseconds.
///
/// Stored separately from [`Blocktime`] (which holds whole seconds) so that the
/// high-precision timestamp exposed via the `HighPrecisionClock` sysvar can be
/// reproduced deterministically during ledger replay. Absent for slots written
/// by older validators, in which case it is treated as `0`.
///
/// * index type: `u64` (see [`SlotColumn`])
/// * value type: `u32`
pub struct BlocktimeNanos;

/// The block hash column
///
/// * index type: `u64` (see [`SlotColumn`])
Expand Down Expand Up @@ -102,6 +115,7 @@ pub fn columns() -> Vec<&'static str> {
AddressSignatures::NAME,
SlotSignatures::NAME,
Blocktime::NAME,
BlocktimeNanos::NAME,
Blockhash::NAME,
Transaction::NAME,
TransactionMemos::NAME,
Expand Down Expand Up @@ -467,6 +481,17 @@ impl TypedColumn for Blocktime {
type Type = solana_clock::UnixTimestamp;
}

// -----------------
// BlocktimeNanos
// -----------------
impl SlotColumn for BlocktimeNanos {}
impl ColumnName for BlocktimeNanos {
const NAME: &'static str = BLOCKTIME_NANOS_CF;
}
impl TypedColumn for BlocktimeNanos {
type Type = u32;
}

// -----------------
// Blockhash
// -----------------
Expand Down
20 changes: 18 additions & 2 deletions magicblock-ledger/src/ledger_truncator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ use crate::{
database::{
columns,
columns::{
AddressSignatures, Blockhash, Blocktime, PerfSamples,
SlotSignatures, Transaction, TransactionMemos, TransactionStatus,
AddressSignatures, Blockhash, Blocktime, BlocktimeNanos,
PerfSamples, SlotSignatures, Transaction, TransactionMemos,
TransactionStatus,
},
},
errors::LedgerResult,
Expand Down Expand Up @@ -181,6 +182,14 @@ impl LedgerTrunctationWorker {
},
);

ledger.delete_range_cf::<BlocktimeNanos>(start, end)?;
<Ledger as HasColumn<BlocktimeNanos>>::with_column(
ledger.as_ref(),
|column| {
column.try_decrease_entry_counter(end - start);
},
);

ledger.delete_range_cf::<PerfSamples>(start, end)?;
<Ledger as HasColumn<PerfSamples>>::with_column(
ledger.as_ref(),
Expand Down Expand Up @@ -345,6 +354,13 @@ impl LedgerTrunctationWorker {
end,
Blocktime
);
compact_cf_or_return!(
ledger,
cancellation_token,
start,
end,
BlocktimeNanos
);
compact_cf_or_return!(
ledger,
cancellation_token,
Expand Down
17 changes: 17 additions & 0 deletions magicblock-ledger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ pub struct LatestBlockInner {
pub slot: u64,
pub blockhash: Hash,
pub clock: Clock,
/// Sub-second component of the block timestamp, in nanoseconds
/// (`[0, 1_000_000_000)`). Together with `clock.unix_timestamp` this forms
/// the high-precision timestamp; `clock.unix_timestamp` is that value
/// rounded down to the whole second.
pub nanos: u32,
}

/// Atomically updated, shared, latest block information
Expand Down Expand Up @@ -45,8 +50,20 @@ impl LatestBlockInner {
slot,
blockhash,
clock,
nanos: 0,
}
}

pub fn new_with_nanos(
slot: u64,
blockhash: Hash,
timestamp: i64,
nanos: u32,
) -> Self {
let mut inner = Self::new(slot, blockhash, timestamp);
inner.nanos = nanos;
inner
}
}

impl Default for LatestBlock {
Expand Down
Loading
Loading