Skip to content

Commit f325fc2

Browse files
committed
Upgrade litesvm to 0.9, re-export InstructionDecoder derive macro
- Update litesvm workspace dep from 0.8 to 0.9, remove all pinned transitive agave/solana deps that are no longer needed - Re-export InstructionDecoder derive macro from main crate so dependents don't need a separate light-instruction-decoder-derive dep - Update tests for litesvm 0.9 API changes
1 parent 1fdd24f commit f325fc2

10 files changed

Lines changed: 163 additions & 1454 deletions

File tree

Cargo.lock

Lines changed: 107 additions & 1338 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,13 @@ syn = { version = "2.0", features = ["visit", "visit-mut", "full"] }
3838
darling = "0.21"
3939
heck = "0.5"
4040
sha2 = "0.10"
41-
# LiteSVM from crates.io (patched locally to git fork via [patch.crates-io])
42-
litesvm = "0.8"
43-
# Pin litesvm transitive deps to =3.0.5 (litesvm not yet compatible with 3.1.x)
44-
agave-feature-set = "=3.0.5"
45-
agave-reserved-account-keys = "=3.0.5"
46-
agave-syscalls = "=3.0.5"
47-
solana-bpf-loader-program = "=3.0.5"
48-
solana-builtins = "=3.0.5"
49-
solana-builtins-default-costs = "=3.0.5"
50-
solana-compute-budget = "=3.0.5"
51-
solana-compute-budget-instruction = "=3.0.5"
52-
solana-compute-budget-program = "=3.0.5"
53-
solana-fee = "=3.0.5"
54-
solana-loader-v4-program = "=3.0.5"
55-
solana-program-runtime = "=3.0.5"
56-
solana-svm-callback = "=3.0.5"
57-
solana-svm-feature-set = "=3.0.5"
58-
solana-svm-log-collector = "=3.0.5"
59-
solana-svm-measure = "=3.0.5"
60-
solana-svm-timings = "=3.0.5"
61-
solana-svm-transaction = "=3.0.5"
62-
solana-svm-type-overrides = "=3.0.5"
63-
solana-system-program = "=3.0.5"
64-
solana-transaction-context = "=3.0.5"
65-
solana-vote-program = "=3.0.5"
41+
# LiteSVM (patched locally via [patch.crates-io])
42+
litesvm = "0.9"
6643
# Testing
6744
insta = { version = "1", features = ["json"] }
6845
# Internal
6946
light-instruction-decoder = { path = "light-instruction-decoder", version = "0.2.0" }
7047
light-instruction-decoder-derive = { path = "light-instruction-decoder-derive", version = "0.2.0" }
7148

7249
[patch.crates-io]
73-
litesvm = { git = "https://github.com/Lightprotocol/litesvm.git", branch = "jorrit/feat-get-program-accounts-v3" }
50+
litesvm = { path = "../litesvm/crates/litesvm" }

light-instruction-decoder/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
//! Note: Most functionality is only available off-chain (not on Solana targets).
2020
2121
// Re-export solana types for use by dependent crates (available on all targets)
22-
// Re-export derive macro for #[instruction_decoder]
22+
// Re-export derive macros for #[derive(InstructionDecoder)] and #[instruction_decoder]
2323
pub use light_instruction_decoder_derive::instruction_decoder;
24+
pub use light_instruction_decoder_derive::InstructionDecoder;
2425
pub use solana_instruction;
2526
pub use solana_pubkey;
2627
pub use solana_signature;

tests/Cargo.toml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,6 @@ solana-program-option = { workspace = true }
2323
zeroize = { workspace = true }
2424
counter = { path = "../examples/counter" }
2525
sha2 = { workspace = true }
26-
# Pin litesvm transitive deps to 3.0.x (litesvm source not yet compatible with 3.1.x)
27-
agave-feature-set = { workspace = true }
28-
agave-reserved-account-keys = { workspace = true }
29-
agave-syscalls = { workspace = true }
30-
solana-bpf-loader-program = { workspace = true }
31-
solana-builtins = { workspace = true }
32-
solana-builtins-default-costs = { workspace = true }
33-
solana-compute-budget = { workspace = true }
34-
solana-compute-budget-instruction = { workspace = true }
35-
solana-compute-budget-program = { workspace = true }
36-
solana-fee = { workspace = true }
37-
solana-loader-v4-program = { workspace = true }
38-
solana-program-runtime = { workspace = true }
39-
solana-svm-callback = { workspace = true }
40-
solana-svm-feature-set = { workspace = true }
41-
solana-svm-log-collector = { workspace = true }
42-
solana-svm-measure = { workspace = true }
43-
solana-svm-timings = { workspace = true }
44-
solana-svm-transaction = { workspace = true }
45-
solana-svm-type-overrides = { workspace = true }
46-
solana-system-program = { workspace = true }
47-
solana-transaction-context = { workspace = true }
48-
solana-vote-program = { workspace = true }
4926

5027
[dev-dependencies]
5128
insta = { workspace = true }

tests/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ pub use light_instruction_decoder::litesvm::{
99

1010
pub use light_instruction_decoder::EnhancedLoggingConfig as Config;
1111
pub use litesvm::LiteSVM;
12+
13+
pub const COUNTER_PROGRAM_PATH: &str = "target/deploy/counter.so";
14+
pub const COUNTER_PROGRAM_BYTES: &[u8] = include_bytes!("../../target/deploy/counter.so");

tests/tests/counter_program.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use instruction_decoder_tests::{
2-
capture_account_states, decode_transaction, decode_transaction_snapshot, format_transaction,
3-
strip_ansi_codes, LiteSVM,
2+
capture_account_states, create_logging_callback, decode_transaction,
3+
decode_transaction_snapshot, format_transaction, strip_ansi_codes, LiteSVM,
4+
COUNTER_PROGRAM_BYTES,
45
};
56
use light_instruction_decoder::EnhancedLoggingConfig;
67
use solana_keypair::{keypair_from_seed, Keypair};
@@ -17,13 +18,19 @@ fn deterministic_keypair(seed_byte: u8) -> Keypair {
1718
keypair_from_seed(&[seed_byte; 32]).unwrap()
1819
}
1920

20-
fn setup() -> (LiteSVM, Keypair) {
21-
let mut svm = LiteSVM::new();
22-
let program_bytes = include_bytes!("../../target/deploy/counter.so");
23-
let _ = svm.add_program(COUNTER_PROGRAM_ID, program_bytes);
21+
fn counter_config() -> EnhancedLoggingConfig {
22+
EnhancedLoggingConfig::debug()
23+
.with_decoders(vec![Box::new(counter::CounterInstructionDecoder)])
24+
}
25+
26+
fn setup() -> (LiteSVM, Keypair, EnhancedLoggingConfig) {
27+
let config = counter_config();
28+
let mut svm = LiteSVM::new()
29+
.with_transaction_callback(create_logging_callback(config.clone()));
30+
let _ = svm.add_program(COUNTER_PROGRAM_ID, COUNTER_PROGRAM_BYTES);
2431
let payer = deterministic_keypair(10);
2532
svm.airdrop(&payer.pubkey(), 10 * LAMPORTS_PER_SOL).unwrap();
26-
(svm, payer)
33+
(svm, payer, config)
2734
}
2835

2936
/// Build an Anchor instruction: 8-byte discriminator + borsh-serialized args
@@ -51,7 +58,7 @@ fn anchor_discriminator(name: &str) -> [u8; 8] {
5158

5259
#[test]
5360
fn test_decode_initialize() {
54-
let (mut svm, payer) = setup();
61+
let (mut svm, payer, config) = setup();
5562
let counter = deterministic_keypair(11);
5663

5764
let init_ix = anchor_ix(
@@ -76,8 +83,6 @@ fn test_decode_initialize() {
7683
let result = svm.send_transaction(versioned_tx.clone());
7784
let post_states = capture_account_states(&svm, &versioned_tx);
7885

79-
let config = EnhancedLoggingConfig::debug()
80-
.with_decoders(vec![Box::new(counter::CounterInstructionDecoder)]);
8186
let snapshot =
8287
decode_transaction_snapshot(&versioned_tx, &result, &config, Some(&pre_states), Some(&post_states));
8388

@@ -101,7 +106,7 @@ fn test_decode_initialize() {
101106

102107
#[test]
103108
fn test_decode_increment_and_set() {
104-
let (mut svm, payer) = setup();
109+
let (mut svm, payer, config) = setup();
105110
let counter = deterministic_keypair(12);
106111

107112
// Initialize
@@ -143,8 +148,6 @@ fn test_decode_increment_and_set() {
143148
let result = svm.send_transaction(versioned_tx.clone());
144149
let post_states = capture_account_states(&svm, &versioned_tx);
145150

146-
let config = EnhancedLoggingConfig::debug()
147-
.with_decoders(vec![Box::new(counter::CounterInstructionDecoder)]);
148151
let snapshot =
149152
decode_transaction_snapshot(&versioned_tx, &result, &config, Some(&pre_states), Some(&post_states));
150153

@@ -181,8 +184,6 @@ fn test_decode_increment_and_set() {
181184
let result = svm.send_transaction(versioned_tx.clone());
182185
let post_states = capture_account_states(&svm, &versioned_tx);
183186

184-
let config = EnhancedLoggingConfig::debug()
185-
.with_decoders(vec![Box::new(counter::CounterInstructionDecoder)]);
186187
let snapshot =
187188
decode_transaction_snapshot(&versioned_tx, &result, &config, Some(&pre_states), Some(&post_states));
188189

@@ -206,7 +207,7 @@ fn test_decode_increment_and_set() {
206207

207208
#[test]
208209
fn test_decode_configure() {
209-
let (mut svm, payer) = setup();
210+
let (mut svm, payer, config) = setup();
210211
let counter = deterministic_keypair(13);
211212

212213
// Initialize first
@@ -277,8 +278,6 @@ fn test_decode_configure() {
277278
let result = svm.send_transaction(versioned_tx.clone());
278279
let post_states = capture_account_states(&svm, &versioned_tx);
279280

280-
let config = EnhancedLoggingConfig::debug()
281-
.with_decoders(vec![Box::new(counter::CounterInstructionDecoder)]);
282281
let snapshot =
283282
decode_transaction_snapshot(&versioned_tx, &result, &config, Some(&pre_states), Some(&post_states));
284283

tests/tests/logging.rs

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use instruction_decoder_tests::{
2-
capture_account_states, decode_transaction, format_transaction, strip_ansi_codes,
3-
TransactionLogger, LiteSVM,
2+
capture_account_states, create_logging_callback, decode_transaction, format_transaction,
3+
strip_ansi_codes, LiteSVM,
44
};
55
use light_instruction_decoder::EnhancedLoggingConfig;
66
use solana_keypair::{keypair_from_seed, Keypair};
@@ -14,33 +14,30 @@ fn deterministic_keypair(seed_byte: u8) -> Keypair {
1414
keypair_from_seed(&[seed_byte; 32]).unwrap()
1515
}
1616

17-
fn setup() -> (LiteSVM, Keypair) {
18-
let mut svm = LiteSVM::new();
17+
fn setup() -> (LiteSVM, Keypair, EnhancedLoggingConfig) {
18+
let config = EnhancedLoggingConfig::debug();
19+
let mut svm = LiteSVM::new()
20+
.with_transaction_callback(create_logging_callback(config.clone()));
1921
let payer = deterministic_keypair(1);
2022
svm.airdrop(&payer.pubkey(), 10 * LAMPORTS_PER_SOL).unwrap();
21-
(svm, payer)
23+
(svm, payer, config)
2224
}
2325

2426
#[test]
2527
fn test_transaction_logger_transfer() {
26-
let (mut svm, payer) = setup();
28+
let (mut svm, payer, config) = setup();
2729
let recipient = deterministic_keypair(2);
2830

29-
let config = EnhancedLoggingConfig::debug();
30-
let logger = TransactionLogger::new(config.clone());
31-
3231
let ix = system_instruction::transfer(&payer.pubkey(), &recipient.pubkey(), LAMPORTS_PER_SOL);
3332
let msg = Message::new(&[ix], Some(&payer.pubkey()));
3433
let tx = Transaction::new(&[&payer], msg, svm.latest_blockhash());
3534
let versioned_tx = solana_transaction::versioned::VersionedTransaction::from(tx);
3635

37-
// Manually capture states so we can also assert the formatted output
3836
let pre_states = capture_account_states(&svm, &versioned_tx);
39-
let result = logger.send_transaction(&mut svm, versioned_tx.clone());
37+
let result = svm.send_transaction(versioned_tx.clone());
4038
assert!(result.is_ok());
4139
let post_states = capture_account_states(&svm, &versioned_tx);
4240

43-
// Re-decode with captured states (logger already logged, but we need the output for snapshot)
4441
let log = decode_transaction(
4542
&versioned_tx,
4643
&result,
@@ -68,12 +65,9 @@ fn test_transaction_logger_transfer() {
6865

6966
#[test]
7067
fn test_transaction_logger_multiple_transactions() {
71-
let (mut svm, payer) = setup();
68+
let (mut svm, payer, _config) = setup();
7269
let recipient = deterministic_keypair(2);
7370

74-
let config = EnhancedLoggingConfig::debug();
75-
let logger = TransactionLogger::new(config.clone());
76-
7771
// Send two transfers
7872
for i in 0..2 {
7973
let ix = system_instruction::transfer(
@@ -84,14 +78,14 @@ fn test_transaction_logger_multiple_transactions() {
8478
let msg = Message::new(&[ix], Some(&payer.pubkey()));
8579
let tx = Transaction::new(&[&payer], msg, svm.latest_blockhash());
8680
let versioned_tx = solana_transaction::versioned::VersionedTransaction::from(tx);
87-
let result = logger.send_transaction(&mut svm, versioned_tx);
81+
let result = svm.send_transaction(versioned_tx);
8882
assert!(result.is_ok());
8983
}
9084
}
9185

9286
#[test]
9387
fn test_account_state_capture_shows_lamport_changes() {
94-
let (mut svm, payer) = setup();
88+
let (mut svm, payer, config) = setup();
9589
let recipient = deterministic_keypair(2);
9690
let transfer_amount = LAMPORTS_PER_SOL;
9791

@@ -115,7 +109,6 @@ fn test_account_state_capture_shows_lamport_changes() {
115109
let recipient_post = post_states.get(&recipient.pubkey()).unwrap();
116110
assert_eq!(recipient_post.0 - recipient_pre.0, transfer_amount);
117111

118-
let config = EnhancedLoggingConfig::debug();
119112
let log = decode_transaction(
120113
&versioned_tx,
121114
&result,
@@ -142,29 +135,20 @@ fn test_account_state_capture_shows_lamport_changes() {
142135

143136
#[test]
144137
fn test_log_file_is_written() {
145-
let (mut svm, payer) = setup();
146-
let recipient = deterministic_keypair(2);
147-
148138
let config = EnhancedLoggingConfig::default();
139+
let mut svm = LiteSVM::new()
140+
.with_transaction_callback(create_logging_callback(config.clone()));
141+
let payer = deterministic_keypair(1);
142+
svm.airdrop(&payer.pubkey(), 10 * LAMPORTS_PER_SOL).unwrap();
143+
let recipient = deterministic_keypair(2);
149144

150145
let ix = system_instruction::transfer(&payer.pubkey(), &recipient.pubkey(), LAMPORTS_PER_SOL);
151146
let msg = Message::new(&[ix], Some(&payer.pubkey()));
152147
let tx = Transaction::new(&[&payer], msg, svm.latest_blockhash());
153148
let versioned_tx = solana_transaction::versioned::VersionedTransaction::from(tx);
154149

155-
let pre_states = capture_account_states(&svm, &versioned_tx);
156150
let result = svm.send_transaction(versioned_tx.clone());
157-
let post_states = capture_account_states(&svm, &versioned_tx);
158-
159-
let log = decode_transaction(
160-
&versioned_tx,
161-
&result,
162-
&config,
163-
Some(&pre_states),
164-
Some(&post_states),
165-
);
166-
let formatted = format_transaction(&log, &config, 1);
167-
instruction_decoder_tests::write_to_log_file(&formatted);
151+
assert!(result.is_ok());
168152

169153
let log_content = std::fs::read_to_string("target/instruction_decoder.log")
170154
.expect("Log file should exist");

tests/tests/snapshots/counter_program__counter_initialize.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ expression: snapshot
66
"signature": "4DySUV8MPozC8yUfFqX9J7r5azJz7MRvhebUjqkQTgmcHHJiFhQptpABSkBe1emRF5odQHYCKU5wrwKMh4bkZrGB",
77
"status": "Success",
88
"fee": 10000,
9-
"compute_used": 4413,
9+
"compute_used": 4359,
1010
"instructions": [
1111
{
1212
"program_id": "Counter111111111111111111111111111111111111",

tests/tests/snapshots/counter_program__counter_initialize_table.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ expression: stripped
44
---
55
┌──────────────────────────────────────────────────────────── Transaction #1 ─────────────────────────────────────────────────────────────┐
66
Transaction: 4DySUV8MPozC8yUfFqX9J7r5azJz7MRvhebUjqkQTgmcHHJiFhQptpABSkBe1emRF5odQHYCKU5wrwKMh4bkZrGB | Slot: 0 | Status: Success
7-
Fee: 0.000010 SOL | Compute Used: 4413/1400000 CU
7+
Fee: 0.000010 SOL | Compute Used: 4359/1400000 CU
88
99
Instructions (1):
1010
@@ -37,6 +37,6 @@ expression: stripped
3737
Instruction: Initialize
3838
Program 11111111111111111111111111111111 invoke [2]
3939
Program 11111111111111111111111111111111 success
40-
Program Counter111111111111111111111111111111111111 consumed 4413 of 200000 compute units
40+
Program Counter111111111111111111111111111111111111 consumed 4359 of 200000 compute units
4141
Program Counter111111111111111111111111111111111111 success
4242
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

0 commit comments

Comments
 (0)