Skip to content
Open
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
17 changes: 16 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
[workspace]
members = ["solana/account", "solana/program-runtime", "solana/svm", "solana/transaction-context"]
members = [
"nucleus",
"programs/magic-root-interface",
"programs/magic-root-program",
"programs/v42-calculator-interface",
"programs/v42-calculator-program",
"solana/account",
"solana/program-runtime",
"solana/svm",
"solana/transaction-context"
]
resolver = "3"

[workspace.package]
Expand All @@ -14,6 +24,7 @@ version = "0.1.0"
[workspace.dependencies]
magic-root-interface = { path = "programs/magic-root-interface" }
magic-root-program = { path = "programs/magic-root-program" }
nucleus = { path = "nucleus", package = "magicblock-engine-nucleus" }
solana-account = { path = "solana/account" }
solana-program-runtime = { path = "solana/program-runtime" }
solana-svm = { path = "solana/svm" }
Expand All @@ -30,6 +41,7 @@ cfg-if = "1.0.4"
criterion = "0.7.0"
derive_more = "2.1.1"
env_logger = "0.11.8"
futures = { version = "0.3.32", default-features = false }
itertools = "0.14.0"
log = "0.4.29"
qualifier_attr = "0.2.2"
Expand All @@ -40,6 +52,9 @@ serde_bytes = "0.11.19"
tar = "0.4.45"
tempfile = "3"
thiserror = "2.0.17"
tokio = "1.52.1"
tokio-util = "0.7.18"
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = ["env-filter", "fmt"] }
wincode = "0.5.1"
zstd = { version = "0.13.3", default-features = false }
Expand Down
85 changes: 85 additions & 0 deletions nucleus/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
[package]
name = "magicblock-engine-nucleus"

authors.workspace = true
edition.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
version.workspace = true

[lib]
name = "nucleus"

[features]
default = []
heed = ["dep:heed"]
ledger-schema = [
"dep:solana-hash",
"dep:wincode",
"solana-hash/copy",
"solana-hash/wincode",
"wincode/derive"
]
metrics = ["dep:prometheus", "dep:tracing"]
notifier = ["dep:tokio"]
runtime = [
"agave-transaction-view/agave-unstable-api",
"dep:agave-transaction-view",
"dep:derive_more",
"dep:oneshot",
"dep:solana-svm",
"dep:solana-transaction-error",
"dep:tokio",
"dep:wincode",
"ledger-schema",
"tokio/sync",
"wincode/derive"
]
shutdown = ["dep:futures", "dep:oneshot", "dep:tokio", "dep:tokio-util", "dep:tracing"]
testkit = [
"dep:solana-instruction",
"dep:solana-keypair",
"dep:solana-message",
"dep:solana-pubkey",
"dep:solana-signature",
"dep:solana-signer",
"dep:solana-transaction",
"dep:tempfile",
"dep:tracing-subscriber",
"dep:v42-calculator-interface",
"ledger-schema",
"solana-transaction/wincode"
]
tls = ["dep:solana-instruction-error", "dep:solana-pubkey", "dep:wincode"]

[dependencies]
derive_more = { workspace = true, optional = true, features = ["deref", "from"] }
futures = { workspace = true, features = ["alloc"], optional = true }
heed = { workspace = true, optional = true }
oneshot = { workspace = true, features = ["async"], optional = true }
prometheus = { workspace = true, optional = true }
solana-hash = { workspace = true, optional = true }
solana-instruction-error = { workspace = true, optional = true }
tempfile = { workspace = true, optional = true }
tokio = { workspace = true, features = ["macros", "signal", "time"], optional = true }
tokio-util = { workspace = true, optional = true }
tracing = { workspace = true, optional = true }
tracing-subscriber = { workspace = true, optional = true }
wincode = { workspace = true, optional = true }

agave-transaction-view = { workspace = true, optional = true }
solana-instruction = { workspace = true, optional = true }
solana-keypair = { workspace = true, optional = true }
solana-message = { workspace = true, optional = true }
solana-pubkey = { workspace = true, optional = true }
solana-signature = { workspace = true, optional = true }
solana-signer = { workspace = true, optional = true }
solana-svm = { workspace = true, optional = true }
solana-transaction = { workspace = true, optional = true }
solana-transaction-error = { workspace = true, optional = true }
v42-calculator-interface = { workspace = true, optional = true }

[lints]
workspace = true
34 changes: 34 additions & 0 deletions nucleus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# `magicblock-engine-nucleus`

The bottom of the stack: the small set of types and helpers that every other
engine crate shares. Its whole job is to be *common vocabulary* — the things you'd
otherwise be tempted to redefine in three places — without smuggling in any
engine policy.
Because it sits under everything, it is built to stay light. Everything is behind
a feature flag, so a dependent pulls in exactly the pieces it uses and nothing
more.

## Feature flags

- **`heed`** — LMDB transaction aliases and the `DatabaseIndex` trait, the shared
shape for the on-disk indexes used by `accountsdb` and `ledger`.
- **`shutdown`** — ordered cooperative cancellation and termination reporting,
so background services can be stopped by priority tier and report why they did.
- **`notifier`** — `EventNotifier`, a one-shot async latch. Once fired it stays
fired: late waiters return immediately and it never resets.
- **`ledger-schema`** — the block-boundary types (`Block`, `SuperblockSeal`) shared
by the storage-adjacent crates that read and write them.
- **`metrics`** — small Prometheus helpers (metric specs, integer collector
constructors, default-registry registration, late-initialized access, operation
labels, and duration/count timers). The helpers are shared; metric names and
registration ownership stay in each crate.
- **`runtime`** — the runtime-facing shared types: sanitized transaction-view
aliases, execution I/O, the sequencer messages and the quiescence `barrier`.
- **`tls`** — thread-local execution state used by runtime-adjacent code:
MagicRoot authority publication and the encoded message queue.
- **`testkit`** — engine-agnostic test fixtures (fixture accounts, wincode
transactions, block boundaries, throwaway directories, and libtest-aware
tracing setup) shared across crate test suites. Compiled as normal code but
only under this feature, so it never reaches release builds; consumers enable
it as a dev-dependency. Keeper-level harness code lives in `keeper::testkit`,
not here.
52 changes: 52 additions & 0 deletions nucleus/src/heed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Shared heed index plumbing.

use std::mem;

use ::heed::{Env, Result, RoTxn, RwTxn, WithTls};

/// Read-only transaction using heed thread-local storage.
pub type RoTxnTls<'e> = RoTxn<'e, WithTls>;
/// Optional write transaction used by batched updates.
pub type OptRwTxn<'t, 'e> = &'t mut Option<RwTxn<'e>>;
/// Optional read transaction used by batched reads.
pub type OptRoTxn<'t, 'e> = &'t mut Option<RoTxnTls<'e>>;

/// Common transaction access for heed-backed indexes.
///
/// # Safety
///
/// Implementors must return an environment owned by `self`, and callers must
/// drop transactions opened through this trait before that environment is
/// dropped. This matches the batched transaction pattern where the transaction
/// is stored in the caller's `Option` and reused across index operations.
pub unsafe trait DatabaseIndex {
/// Returns the owning heed environment.
fn env(&self) -> &Env;

/// Uses the supplied write transaction or opens one on demand.
fn write_txn<'t, 'e>(&self, txn: OptRwTxn<'t, 'e>) -> Result<&'t mut RwTxn<'e>> {
if let Some(txn) = txn {
return Ok(txn);
}
// SAFETY: guaranteed by the trait contract. The transaction is stored
// in the caller-owned option and must be dropped before `env`.
let write = unsafe { mem::transmute::<RwTxn<'_>, RwTxn<'e>>(self.env().write_txn()?) };
Ok(txn.insert(write))
}

/// Uses the supplied read transaction or opens one on demand.
fn read_txn<'t, 'e>(&self, txn: OptRoTxn<'t, 'e>) -> Result<&'t RoTxnTls<'e>> {
if let Some(txn) = txn {
return Ok(txn);
}
// SAFETY: guaranteed by the trait contract. The transaction is stored
// in the caller-owned option and must be dropped before `env`.
let read = unsafe { mem::transmute::<RoTxnTls<'_>, RoTxnTls<'e>>(self.env().read_txn()?) };
Ok(txn.insert(read))
}

/// Flushes the index databases to durable storage.
fn flush(&self) -> Result<()> {
self.env().force_sync()
}
}
26 changes: 26 additions & 0 deletions nucleus/src/ledger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Ledger block-boundary schema shared by storage-adjacent crates.

use solana_hash::Hash;
use wincode::{SchemaRead, SchemaWrite};

use crate::Slot;

/// Block boundary entry stored after all transactions in the block.
#[derive(SchemaRead, SchemaWrite, Clone, Copy, Default)]
pub struct Block {
/// Slot that produced the block.
pub slot: Slot,
/// Block hash for `slot`.
pub hash: Hash,
/// Block timestamp in the producer's time base.
pub time: i64,
}

/// Superblock boundary entry stored at the end of the blockstore stream.
#[derive(SchemaRead, SchemaWrite, Clone, Copy)]
pub struct SuperblockSeal {
/// Checksum of accountsdb at the moment the superblock was sealed.
pub checksum: u64,
/// Total transactions written before this seal.
pub transactions: u64,
}
32 changes: 32 additions & 0 deletions nucleus/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#![doc = include_str!("../README.md")]

#[cfg(feature = "heed")]
pub mod heed;

#[cfg(feature = "shutdown")]
pub mod shutdown;

#[cfg(feature = "notifier")]
pub mod notifier;

#[cfg(feature = "ledger-schema")]
pub mod ledger;

#[cfg(feature = "metrics")]
pub mod metrics;

#[cfg(feature = "runtime")]
pub mod runtime;

#[cfg(feature = "testkit")]
pub mod testkit;

#[cfg(feature = "tls")]
pub mod tls;

/// Ledger slot number.
pub type Slot = u64;
/// One mebibyte in bytes.
pub const MB: usize = 1024 * 1024;
/// One gibibyte in bytes.
pub const GB: usize = 1024 * MB;
Loading