3

假设我想设计一个类似于众筹或拍卖的系统。有一个固定的时间段来运行这样的事件。我是否可以启动一个后台线程,该线程将定期检查是否已达到事件的结束时间并随后关闭该事件?我正在查看futures板条箱(和其他一些),但它可以在 Substrate 中使用吗?有没有关于如何处理这种情况的最佳实践?

4

1 回答 1

5

我相信答案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.
    }
}
于 2021-01-11T07:11:50.570 回答