Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b5c75cb
extract default ledger info to testutils function
leighmcculloch Nov 14, 2025
ff856db
use unqualified import for default_ledger_info
leighmcculloch Nov 14, 2025
f0af184
reorder testutils imports alphabetically
leighmcculloch Nov 14, 2025
3db0574
make ledger_info optional in new_for_testutils
leighmcculloch Nov 14, 2025
e863fb1
make default_ledger_info pub(crate)
leighmcculloch Nov 14, 2025
9ac76d7
accept custom snapshot source input types as ledger snapshots
leighmcculloch Nov 14, 2025
594aef5
remove redundant clone in SnapshotSourceInput from
leighmcculloch Nov 14, 2025
c857851
expose HostError in testutils module
leighmcculloch Nov 14, 2025
1146edf
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Nov 14, 2025
1fd662c
store test name and env number in env itself
leighmcculloch Nov 17, 2025
678cf69
rename LastEnv field 'name' to 'test_name'
leighmcculloch Nov 17, 2025
2196218
update snapshot file numbering documentation
leighmcculloch Nov 17, 2025
6569681
wrap snapshot in RefCell and add cache-write layer
leighmcculloch Nov 17, 2025
033a529
Merge branch 'rs-soroban-sdk-file-number-at-start' into rs-soroban-sd…
leighmcculloch Nov 17, 2025
b5d22ef
add ledger snapshot before file capture in tests
leighmcculloch Nov 17, 2025
12799ba
move file number calculation before env initialization
leighmcculloch Nov 17, 2025
ff3f7b4
Merge branch 'rs-soroban-sdk-file-number-at-start' into rs-soroban-sd…
leighmcculloch Nov 17, 2025
cf0da97
add snapshot source fallback to test snapshots
leighmcculloch Nov 17, 2025
33db562
reformat snapshot path and footprint initialization
leighmcculloch Nov 17, 2025
62b2387
remove snapshot caching layer from env creation
leighmcculloch Nov 17, 2025
03f2145
simplify snapshot mapping in env.rs
leighmcculloch Nov 17, 2025
051f873
rename SnapshotSourceCacheWrite to SnapshotSourceCache
leighmcculloch Nov 17, 2025
06921c3
add debug log for snapshot source file path
leighmcculloch Nov 17, 2025
922026e
limit cache borrow scope in snapshot source get
leighmcculloch Nov 17, 2025
5cd5b02
format multiline eprintln in snapshot source
leighmcculloch Nov 18, 2025
ca6cc9b
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Nov 19, 2025
2a39c41
move LedgerEntry and LedgerKey to crate::xdr
leighmcculloch Nov 19, 2025
a50427f
add self to xdr import
leighmcculloch Nov 19, 2025
8a6292b
rename snapshot before to source
leighmcculloch Nov 19, 2025
b048ca1
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Nov 28, 2025
80057f2
undo auto source persisting and loading
leighmcculloch Nov 28, 2025
23779c1
add HostError to public use
leighmcculloch Nov 28, 2025
f4b9d1d
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Dec 3, 2025
8baa295
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Dec 12, 2025
f7527ed
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Dec 15, 2025
eef97ad
add documentation for snapshot source types and conversion
leighmcculloch Dec 15, 2025
37badee
Merge branch 'main' into rs-soroban-sdk-snapshot-source
leighmcculloch Dec 16, 2025
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
20 changes: 13 additions & 7 deletions soroban-sdk/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ use crate::{
testutils::{
budget::Budget, default_ledger_info, Address as _, AuthSnapshot, AuthorizedInvocation,
ContractFunctionSet, EventsSnapshot, Generators, Ledger as _, MockAuth, MockAuthContract,
Register, Snapshot, StellarAssetContract, StellarAssetIssuer,
Register, Snapshot, SnapshotSourceInput, StellarAssetContract, StellarAssetIssuer,
},
Bytes, BytesN, ConstructorArgs,
};
Expand Down Expand Up @@ -1597,16 +1597,22 @@ impl Env {
self.to_snapshot().write_file(p).unwrap();
}

/// Creates a new Env loaded with the [`LedgerSnapshot`].
/// Creates a new Env loaded with the snapshot source.
///
/// The ledger info and state in the snapshot are loaded into the Env.
pub fn from_ledger_snapshot(s: LedgerSnapshot) -> Env {
/// The ledger info and state from the snapshot source are loaded into the Env.
pub fn from_ledger_snapshot(input: impl Into<SnapshotSourceInput>) -> Env {
let SnapshotSourceInput {
source,
ledger_info,
snapshot,
} = input.into();

Env::new_for_testutils(
EnvTestConfig::default(), // TODO: Allow setting the config.
Rc::new(s.clone()),
source,
None,
Some(s.ledger_info()),
Some(Rc::new(s.clone())),
ledger_info,
snapshot,
)
}

Expand Down
87 changes: 87 additions & 0 deletions soroban-sdk/src/testutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ use soroban_ledger_snapshot::LedgerSnapshot;

pub use crate::env::EnvTestConfig;

/// Trait for providing ledger data to the test environment.
///
/// Implement this trait to create custom snapshot sources that load ledger state
/// from sources other than [`LedgerSnapshot`] files, such as RPC endpoints,
/// history archives, or in-memory data structures.
///
/// Use with [`SnapshotSourceInput`] and [`Env::from_ledger_snapshot`] to initialize
/// a test environment from a custom source.
pub use crate::env::internal::storage::SnapshotSource;

/// Error type returned by [`SnapshotSource::get`].
///
/// Required for implementing custom snapshot sources.
pub use crate::env::internal::HostError;

pub trait Register {
fn register<'i, I, A>(self, env: &Env, id: I, args: A) -> crate::Address
where
Expand Down Expand Up @@ -605,3 +620,75 @@ impl StellarAssetContract {
self.asset.clone()
}
}

/// Input for creating an [`Env`] from a custom snapshot source.
///
/// This struct enables [`Env::from_ledger_snapshot`] to accept custom snapshot
/// source types beyond [`LedgerSnapshot`], providing flexibility for testing
/// scenarios that load ledger state from different sources such as RPC endpoints,
/// history archives, or in-memory data structures.
///
/// # Fields
///
/// * `source` - A snapshot source implementing the [`SnapshotSource`] trait.
/// This is used to load ledger entries on demand during test execution.
///
/// * `ledger_info` - Optional ledger info to initialize the environment with.
/// If `None`, default test ledger info is used.
///
/// * `snapshot` - Optional [`LedgerSnapshot`] used as the base for capturing
/// state changes. When the test completes, modified entries are written to
/// this snapshot. If `None`, a new empty snapshot is created.
///
/// # Example
///
/// ```
/// use soroban_sdk::testutils::{SnapshotSource, SnapshotSourceInput, HostError};
/// use soroban_sdk::xdr::{LedgerEntry, LedgerKey};
/// use soroban_sdk::Env;
/// use std::rc::Rc;
///
/// struct MyCustomSource;
///
/// impl SnapshotSource for MyCustomSource {
/// fn get(
/// &self,
/// key: &Rc<LedgerKey>,
/// ) -> Result<Option<(Rc<LedgerEntry>, Option<u32>)>, HostError> {
/// // Return None for keys not found, or Some((entry, live_until_ledger))
/// Ok(None)
/// }
/// }
///
/// let input = SnapshotSourceInput {
/// source: Rc::new(MyCustomSource),
/// ledger_info: None,
/// snapshot: None,
/// };
/// let env = Env::from_ledger_snapshot(input);
/// ```
pub struct SnapshotSourceInput {
pub source: Rc<dyn SnapshotSource>,
pub ledger_info: Option<LedgerInfo>,
pub snapshot: Option<Rc<LedgerSnapshot>>,
}

/// Converts a [`LedgerSnapshot`] into a [`SnapshotSourceInput`].
///
/// This conversion maintains backward compatibility with the existing API,
/// allowing [`LedgerSnapshot`] to be used directly with [`Env::from_ledger_snapshot`].
///
/// The [`LedgerSnapshot`] is wrapped in an [`Rc`] and used for all three fields:
/// - As the snapshot source for loading ledger entries
/// - To provide the ledger info for the environment
/// - As the base snapshot for capturing state changes
impl From<LedgerSnapshot> for SnapshotSourceInput {
fn from(s: LedgerSnapshot) -> Self {
let s = Rc::new(s);
Self {
source: s.clone(),
ledger_info: Some(s.ledger_info()),
snapshot: Some(s),
}
}
}
Loading