Solana Anchor测试:如何模拟时间推进调整Clock的unix_timestamp值
问题解答
这个需求完全可以实现,你可以通过Anchor测试框架提供的自定义Sysvar能力,手动修改测试环境中Clock sysvar的时间戳,该修改仅作用于本地测试环境,不会影响链上正式环境的逻辑。
TypeScript/JavaScript 测试环境实现(Anchor最常用测试方案)
- 直接调用Anchor封装的
anchor.setClock()方法,传入你需要模拟的时间戳即可,无需修改任何链上程序代码,示例如下:
import * as anchor from "@coral-xyz/anchor"; // 模拟设置为2024年1月1日0点的Unix时间戳(单位为秒) const mockTimestamp = 1704067200; await anchor.setClock({ unixTimestamp: mockTimestamp, // 其余Clock相关字段(slot、epoch等)如果不需要自定义可省略,保留默认值即可 });
- 方法调用完成后,后续所有程序测试请求中,
Clock::get().unwrap().unix_timestamp获取到的就是你设置的模拟值。 - 不同测试用例可以单独设置对应时间,实现多时间场景的差异化测试。
Rust 原生测试环境实现
如果使用Anchor的Rust原生测试框架,可以通过ProgramTest注入自定义的Clock Sysvar:
use solana_program::sysvar::clock::Clock; use solana_program_test::ProgramTest; use solana_sdk::sysvar::Sysvar; let mut test = ProgramTest::default(); // 构造自定义Clock实例 let mock_clock = Clock { unix_timestamp: 1704067200, ..Clock::default() }; // 将自定义Clock注入测试环境 test.add_sysvar(&mock_clock).unwrap(); // 后续启动测试后,程序获取到的Clock就是你设置的模拟值
注意事项
- 该自定义能力仅支持本地测试验证器环境,你无法在主网、公开测试网中修改链上Clock Sysvar的实际值,符合链上Sysvar的不可篡改规则。
- 时间戳单位为秒,和
unix_timestamp字段的定义完全一致,无需额外单位转换。
内容的提问来源于stack exchange,提问作者Russo
相关产品推荐
相关产品推荐

