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
1 change: 1 addition & 0 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions crates/core/src/rpc/full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2626,7 +2626,7 @@ mod tests {
setup
.context
.svm_locker
.confirm_current_block(&None)
.confirm_current_block()
.await
.unwrap();
let res = setup
Expand Down Expand Up @@ -3386,7 +3386,7 @@ mod tests {
setup
.context
.svm_locker
.confirm_current_block(&None)
.confirm_current_block()
.await
.unwrap();
}
Expand Down Expand Up @@ -3431,7 +3431,7 @@ mod tests {
setup
.context
.svm_locker
.confirm_current_block(&None)
.confirm_current_block()
.await
.unwrap();
}
Expand Down
104 changes: 75 additions & 29 deletions crates/core/src/rpc/surfnet_cheatcodes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::BTreeMap;

use base64::{Engine as _, engine::general_purpose::STANDARD};
use jsonrpc_core::{BoxFuture, Error, Result, futures::future};
use jsonrpc_derive::rpc;
Expand All @@ -14,9 +12,9 @@ use solana_system_interface::program as system_program;
use solana_transaction::versioned::VersionedTransaction;
use spl_associated_token_account_interface::address::get_associated_token_address_with_program_id;
use surfpool_types::{
AccountSnapshot, ClockCommand, ExportSnapshotConfig, GetStreamedAccountsResponse,
GetSurfnetInfoResponse, Idl, ResetAccountConfig, RpcProfileResultConfig, Scenario,
SimnetCommand, SimnetEvent, StreamAccountConfig, UiKeyedProfileResult,
ClockCommand, ExportSnapshotConfig, GetStreamedAccountsResponse, GetSurfnetInfoResponse, Idl,
ResetAccountConfig, RpcProfileResultConfig, Scenario, SimnetCommand, SimnetEvent,
SnapshotResult, StreamAccountConfig, UiKeyedProfileResult,
types::{AccountUpdate, SetSomeAccount, SupplyUpdate, TokenAccountUpdate, UuidOrSignature},
};

Expand Down Expand Up @@ -841,7 +839,7 @@ pub trait SurfnetCheatcodes {
&self,
meta: Self::Metadata,
config: Option<ExportSnapshotConfig>,
) -> Result<RpcResponse<BTreeMap<String, AccountSnapshot>>>;
) -> BoxFuture<Result<RpcResponse<SnapshotResult>>>;

/// A cheat code to simulate account streaming.
/// When a transaction is processed, the accounts that are accessed are downloaded from the datasource and cached in the SVM.
Expand Down Expand Up @@ -1127,7 +1125,7 @@ pub trait SurfnetCheatcodes {
meta: Self::Metadata,
scenario: Scenario,
slot: Option<Slot>,
) -> Result<RpcResponse<()>>;
) -> BoxFuture<Result<RpcResponse<()>>>;
}

#[derive(Clone)]
Expand Down Expand Up @@ -1794,13 +1792,30 @@ impl SurfnetCheatcodes for SurfnetCheatcodesRpc {
&self,
meta: Self::Metadata,
config: Option<ExportSnapshotConfig>,
) -> Result<RpcResponse<BTreeMap<String, AccountSnapshot>>> {
) -> BoxFuture<Result<RpcResponse<SnapshotResult>>> {
let config = config.unwrap_or_default();
let svm_locker = meta.get_svm_locker()?;
let snapshot = svm_locker.export_snapshot(config);
Ok(RpcResponse {
context: RpcResponseContext::new(svm_locker.get_latest_absolute_slot()),
value: snapshot,

Box::pin(async move {
let SurfnetRpcContext {
svm_locker,
remote_ctx,
} = meta.get_rpc_context(CommitmentConfig::confirmed())?;

match &config.scope {
surfpool_types::ExportSnapshotScope::Network => todo!(),
surfpool_types::ExportSnapshotScope::PreTransaction(_) => todo!(),
surfpool_types::ExportSnapshotScope::Scenario(scenario) => {
svm_locker
.fetch_scenario_override_accounts(&remote_ctx, &scenario)
.await?;
}
};

let snapshot = svm_locker.export_snapshot(config);
Ok(RpcResponse {
context: RpcResponseContext::new(svm_locker.get_latest_absolute_slot()),
value: snapshot,
})
})
}

Expand All @@ -1809,18 +1824,29 @@ impl SurfnetCheatcodes for SurfnetCheatcodesRpc {
meta: Self::Metadata,
scenario: Scenario,
slot: Option<Slot>,
) -> Result<RpcResponse<()>> {
let svm_locker = meta.get_svm_locker()?;
svm_locker.register_scenario(scenario, slot)?;
Ok(RpcResponse {
context: RpcResponseContext::new(svm_locker.get_latest_absolute_slot()),
value: (),
) -> BoxFuture<Result<RpcResponse<()>>> {
Box::pin(async move {
let SurfnetRpcContext {
svm_locker,
remote_ctx,
} = meta.get_rpc_context(CommitmentConfig::confirmed())?;
svm_locker
.fetch_scenario_override_accounts(&remote_ctx, &scenario)
.await?;

svm_locker.register_scenario(scenario, slot)?;
Ok(RpcResponse {
context: RpcResponseContext::new(svm_locker.get_latest_absolute_slot()),
value: (),
})
})
}
}

#[cfg(test)]
mod tests {
use std::collections::BTreeMap;

use solana_account_decoder::{
UiAccountData, UiAccountEncoding, parse_account_data::ParsedAccount,
};
Expand All @@ -1837,8 +1863,8 @@ mod tests {
use spl_token_2022_interface::instruction::{initialize_mint2, mint_to, transfer_checked};
use spl_token_interface::state::Mint;
use surfpool_types::{
ExportSnapshotFilter, ExportSnapshotScope, RpcProfileDepth, UiAccountChange,
UiAccountProfileState,
AccountSnapshot, ExportSnapshotFilter, ExportSnapshotScope, RpcProfileDepth,
UiAccountChange, UiAccountProfileState,
};

use super::*;
Expand Down Expand Up @@ -2676,8 +2702,8 @@ mod tests {
assert_eq!(expected_account.rent_epoch, account.rent_epoch);
}

#[test]
fn test_export_snapshot() {
#[tokio::test]
async fn test_export_snapshot() {
let client = TestSetup::new(SurfnetCheatcodesRpc);

let pubkey1 = Pubkey::new_unique();
Expand Down Expand Up @@ -2705,15 +2731,18 @@ mod tests {
let snapshot = client
.rpc
.export_snapshot(Some(client.context.clone()), None)
.await
.expect("Failed to export snapshot")
.value;

let snapshot = snapshot.as_accounts().unwrap();

verify_snapshot_account(&snapshot, &pubkey1, &account1);
verify_snapshot_account(&snapshot, &pubkey2, &account2);
}

#[test]
fn test_export_snapshot_json_parsed() {
#[tokio::test]
async fn test_export_snapshot_json_parsed() {
let client = TestSetup::new(SurfnetCheatcodesRpc);

let pubkey1 = Pubkey::new_unique();
Expand Down Expand Up @@ -2762,10 +2791,14 @@ mod tests {
scope: ExportSnapshotScope::Network,
}),
)
.await
.expect("Failed to export snapshot")
.value;

let snapshot = snapshot.as_accounts().unwrap();

verify_snapshot_account(&snapshot, &pubkey1, &account1);

let actual_account1 = snapshot
.get(&pubkey1.to_string())
.expect("Account fixture not found");
Expand Down Expand Up @@ -2803,8 +2836,8 @@ mod tests {
);
}

#[test]
fn test_export_snapshot_pre_transaction() {
#[tokio::test]
async fn test_export_snapshot_pre_transaction() {
use std::collections::HashMap;

use solana_signature::Signature;
Expand Down Expand Up @@ -2890,9 +2923,12 @@ mod tests {
scope: ExportSnapshotScope::PreTransaction(signature.to_string()),
}),
)
.await
.expect("Failed to export snapshot")
.value;

let snapshot = snapshot.as_accounts().unwrap();

// Verify that only account1 and account2 are in the snapshot
assert!(
snapshot.contains_key(&account1_pubkey.to_string()),
Expand Down Expand Up @@ -2937,8 +2973,8 @@ mod tests {
);
}

#[test]
fn test_export_snapshot_filtering() {
#[tokio::test]
async fn test_export_snapshot_filtering() {
let system_account_pubkey = Pubkey::new_unique();
println!("System Account Pubkey: {}", system_account_pubkey);
let excluded_system_account_pubkey = Pubkey::new_unique();
Expand Down Expand Up @@ -2979,8 +3015,12 @@ mod tests {
let snapshot = client
.rpc
.export_snapshot(Some(client.context.clone()), None)
.await
.expect("Failed to export snapshot")
.value;

let snapshot = snapshot.as_accounts().unwrap();

assert!(
!snapshot.contains_key(&program_account_pubkey.to_string()),
"Program account should be excluded by default"
Expand All @@ -3001,8 +3041,12 @@ mod tests {
..Default::default()
}),
)
.await
.expect("Failed to export snapshot")
.value;

let snapshot = snapshot.as_accounts().unwrap();

assert!(
!snapshot.contains_key(&program_account_pubkey.to_string()),
"Program account should be excluded by default"
Expand All @@ -3025,8 +3069,10 @@ mod tests {
..Default::default()
}),
)
.await
.expect("Failed to export snapshot")
.value;
let snapshot = snapshot.as_accounts().unwrap();

assert!(
snapshot.contains_key(&program_account_pubkey.to_string()),
Expand Down
8 changes: 3 additions & 5 deletions crates/core/src/runloops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ pub async fn start_block_production_runloop(
}
SimnetCommand::UpdateInternalClock(_, clock) => {
// Confirm the current block to materialize any scheduled overrides for this slot
if let Err(e) = svm_locker.confirm_current_block(&remote_client_with_commitment).await {
if let Err(e) = svm_locker.confirm_current_block().await {
let _ = svm_locker.simnet_events_tx().send(SimnetEvent::error(format!(
"Failed to confirm block after time travel: {}", e
)));
Expand All @@ -281,7 +281,7 @@ pub async fn start_block_production_runloop(
}
SimnetCommand::UpdateInternalClockWithConfirmation(_, clock, response_tx) => {
// Confirm the current block to materialize any scheduled overrides for this slot
if let Err(e) = svm_locker.confirm_current_block(&remote_client_with_commitment).await {
if let Err(e) = svm_locker.confirm_current_block().await {
let _ = svm_locker.simnet_events_tx().send(SimnetEvent::error(format!(
"Failed to confirm block after time travel: {}", e
)));
Expand Down Expand Up @@ -348,9 +348,7 @@ pub async fn start_block_production_runloop(

{
if do_produce_block {
svm_locker
.confirm_current_block(&remote_client_with_commitment)
.await?;
svm_locker.confirm_current_block().await?;
}
}
}
Expand Down
Loading
Loading