如何在JavaScript中控制solana-test-validator的时钟?
如何在JavaScript中动态快进Solana测试验证器的时间(无需重启)
完全理解你的痛点——依赖Clock系统变量的Solana程序测试,每次用--warp-slot重启验证器确实太折腾,尤其是在Anchor的工作流里。好在solana-test-validator早就支持动态修改时钟的自定义RPC方法,不用重启就能直接在JavaScript测试代码里完成时间快进,完美适配你的现有JS测试栈。
下面是具体的实现步骤:
1. 确认验证器版本
这个动态调时间的功能需要solana-test-validator v1.10及以上版本,先检查你的版本:
solana-test-validator --version
如果版本过低,直接用solana update升级即可。
2. 封装JavaScript时间快进函数
用@solana/web3.js的Connection实例发送自定义RPC请求,调用测试验证器的set_clock方法:
import { Connection } from "@solana/web3.js"; /** * 快进Solana测试验证器的时钟到指定时间戳 * @param connection Solana RPC连接实例 * @param targetUnixTimestamp 目标Unix时间戳(秒级) */ async function warpClock(connection, targetUnixTimestamp) { // 调用测试验证器专属的set_clock RPC方法 await connection.sendRpcRequest("set_clock", [ { unix_timestamp: targetUnixTimestamp } // 可选:如果需要同步调整slot,可添加slot字段,比如 slot: 123456 ]); // 可选:验证时间是否已更新 const clock = await connection.getClock(); console.log("时钟已快进到:", new Date(clock.unixTimestamp * 1000)); }
3. 结合Anchor测试框架使用
如果你用Anchor写测试,可以直接在测试用例里调用这个函数,无缝融入现有流程:
import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import { YourProgram } from "../target/types/your_program"; describe("your-program", () => { const provider = anchor.AnchorProvider.env(); anchor.setProvider(provider); const program = anchor.workspace.YourProgram as Program<YourProgram>; it("测试时间依赖的程序逻辑", async () => { // 先完成初始化操作(比如创建账户、调用初始化指令) // 快进到1小时后 const targetTime = Math.floor(Date.now() / 1000) + 3600; await warpClock(provider.connection, targetTime); // 执行依赖时间的程序指令(比如到期结算、时间锁解锁等) await program.methods .yourTimeDependentInstruction() .accounts({ /* 账户配置 */ }) .rpc(); // 验证执行结果是否符合预期 }); });
关键注意事项
set_clock是测试验证器独有的方法,只能在本地测试环境使用,主网/测试网绝对不支持(毕竟不能随便篡改链上时间)。- 如果需要同时调整slot和时间,可以在RPC参数里同时传入
slot和unix_timestamp,但大多数情况下只需要指定时间戳,验证器会自动计算对应的slot值。 - 确保你的测试验证器没有加
--no-rpc参数,否则无法接收RPC请求。
内容的提问来源于stack exchange,提问作者Ruven Salamon




