假设我想设计一个类似于众筹或拍卖的系统。有一个固定的时间段来运行这样的事件。我是否可以启动一个后台线程,该线程将定期检查是否已达到事件的结束时间并随后关闭该事件?我正在查看futures
板条箱(和其他一些),但它可以在 Substrate 中使用吗?有没有关于如何处理这种情况的最佳实践?
1 回答
我相信答案futures
是否定的。这里有更多解释:
我认为最好考虑一下Substrate 运行时中可用的编程原语,而不是尝试使用通用编程中的概念(future
)并尝试将其重新用于 Substrate 运行时(自上而下与底部-向上的观点)。
所以,让我们考虑一下运行时的生命周期,看看那里有什么意义:
在运行时,你有点被困在一个盒子里。每当有新块要导入(或编写,但我们假设现在只是导入)时,(总是本机的)客户端会生成和执行(wasm)运行时代码,然后杀死并搁置(至少从运行时的观点——客户端有运行时缓存)。我的观点是,在每个块的执行结束时,您未承诺声明(即写入存储)的任何内容都会丢失。这包括所有局部变量、堆栈、堆和其他任何东西。因此,即使您要使用 future 来生成任务,它也并不真正适合 Substrate 运行时的编程模型,因为即使该未来存在于运行时中,一旦块完成,wasm 实例就是死了,未来也一样。
这一切都忽略了您只能使用no_std
运行时支持的 crate 的事实,因此并非每个异步库都可用。
正如我所暗示的那样,主要的解决方案可能是使用状态存储来记录拍卖的起点,这样x块之后你仍然可以知道你什么时候开始的,如果超过了某个阈值,那么你就可以完成你的拍卖。您可以在拍卖期间使用时间戳或区块数。类似于以下内容:
trait Config: frame_system::Config {
// duration in time or block number
type AuctionDuration<T::BlockNumber>;
}
// inside your on_initialize
fn on_initialize(n: T::BlockNumber) {
if n % T::AuctionDuration::get() == 0 {
// ^^^^^ note: ensure this is non-zero, else panic in runtime might happen.
// time to close the auction.
}
}