Solana 文档LiteSVMRust附加模块litesvm-loader

快速入门

安装

请确保您已安装所有必要的依赖项:

cargo add --dev litesvm litesvm-loader solana-keypair solana-signer

如果您的测试直接调用已部署的程序,请同时添加测试所使用的 Solana 指令和交易 crate:

cargo add --dev solana-instruction solana-message solana-transaction

什么是 litesvm-loader?

litesvm-loader crate 提供了一系列辅助工具,用于在 LiteSVM 中通过 BPF 可升级加载器部署程序。当您的测试需要加载器所有的 program account、program data account 或升级权限行为,而非直接通过 svm.add_program(...) 插入程序时,请使用该 crate。

可升级部署

  • 创建加载器缓冲账户
  • 分块写入程序字节
  • 使用 BPF 可升级加载器部署最终的 program account
  • 使用提供的程序 keypair 作为程序 ID

升级权限管理 - 更改已部署程序的升级权限 - 支持分配新的权限方 - 支持传入 None 以使程序不可变

真实加载器状态

  • 模拟程序在链上所见的相同加载器账户模型
  • 允许测试检查 program account 和 program data account
  • 有助于发现直接插入程序时所隐藏的错误

对于大多数测试,svm.add_program(program_id, program_bytes) 仍然是 加载程序最快、最简单的方式。当 加载器账户布局或升级权限是您需要测试的内容时,请使用 litesvm-loader

快速示例

以下是一个完整示例,通过可升级加载器部署程序然后轮换其权限:

use litesvm::LiteSVM;
use litesvm_loader::{deploy_upgradeable_program, set_upgrade_authority};
use solana_keypair::Keypair;
use solana_signer::Signer;
#[test]
fn test_upgradeable_deployment() {
let mut svm = LiteSVM::new();
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();
// Use the keypair that should own the program ID.
// For Anchor programs, this is usually target/deploy/<program>-keypair.json.
let program = Keypair::new();
let program_bytes = include_bytes!("../target/deploy/my_program.so");
deploy_upgradeable_program(&mut svm, &payer, &program, program_bytes).unwrap();
let program_account = svm.get_account(&program.pubkey()).unwrap();
assert!(program_account.executable);
let new_authority = Keypair::new();
set_upgrade_authority(
&mut svm,
&payer,
&program.pubkey(),
&payer,
Some(&new_authority.pubkey()),
)
.unwrap();
}

选择程序 keypair

deploy_upgradeable_program 使用 program_kp 参数作为程序地址。如果您的程序声明了固定 ID,请加载生成的部署 keypair 而不是创建随机 keypair:

use solana_keypair::read_keypair_file;
let program = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();
deploy_upgradeable_program(&mut svm, &payer, &program, program_bytes).unwrap();

调用已部署的程序

部署后,以与调用任何 LiteSVM 加载程序相同的方式调用该程序。为您的程序构建指令,签署交易,并通过同一个 LiteSVM 实例发送:

use solana_instruction::Instruction;
use solana_message::Message;
use solana_transaction::Transaction;
let instruction = Instruction::new_with_bytes(
program.pubkey(),
&[], // instruction data for your program
vec![], // account metas for your program
);
let message = Message::new(&[instruction], Some(&payer.pubkey()));
let tx = Transaction::new(&[&payer], message, svm.latest_blockhash());
svm.send_transaction(tx).unwrap();

关键组件

deploy_upgradeable_program

参数描述
svm接收已部署程序的可变 LiteSVM 实例
payer_kp手续费支付方及初始升级权限
program_kp公钥作为程序 ID 的 keypair
program_bytes已编译的 SBF 程序字节,通常来自 target/deploy/*.so

deploy_upgradeable_program 创建一个加载器缓冲区,以 512 字节块写入程序字节,并部署程序,为未来升级预留空间。

set_upgrade_authority

参数描述
svm包含已部署程序的可变 LiteSVM 实例
from_keypair交易的手续费支付方及签名权限
program_address需要更改权限的程序 ID
current_authority_keypair当前升级权限 keypair
new_authority_address新权限地址,或 None 以使程序不可变

在当前的辅助函数实现中,生成的交易由 from_keypair 签名。在更改升级权限时,请将当前权限作为 from_keypair 传入,或保持付款方与当前权限使用同一 keypair。

常见工作流

使用已声明的程序 ID 部署

use solana_keypair::read_keypair_file;
let program = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();
let program_bytes = include_bytes!("../target/deploy/my_program.so");
deploy_upgradeable_program(&mut svm, &payer, &program, program_bytes).unwrap();

使程序不可变

set_upgrade_authority(
&mut svm,
&payer,
&program.pubkey(),
&payer,
None,
)
.unwrap();

故障排查

常见错误

错误原因解决方案
ProgramAccountNotFound 或针对错误 ID 的指令失败部署时使用了随机的 Keypair,而程序期望使用已声明的 ID读取 target/deploy/<program>-keypair.json 并将该 keypair 传入 deploy_upgradeable_program
InsufficientFunds付款方没有足够的 lamport 用于加载器缓冲区和 program account在部署前空投更多 lamport
更改权限时出现 MissingRequiredSignature当前权限未对交易进行签名将当前权限作为 from_keypair 传入,或将付款方与当前权限保持为同一 keypair
程序部署速度低于预期加载器部署通过真实的加载器指令逐字节写入当不需要加载器状态或升级权限行为时,请使用 svm.add_program(...)

Is this page helpful?

Table of Contents

Edit Page
©️ 2026 Solana 基金会版权所有