RPC Macro介绍
WASM RPC客户端如何处理响应的类型转换?使用get_info()示例,假设内部/包装的客户端返回 kaspa-rpc-core::model::messages::GetInfoResponse,WASM rpc客户端通过try_into()转换为某种JS/TS类型。在build_wrpc_wasm_bindgen_interface中看到了这一点!macro。
客户端:
宏macro创建一个传递请求并获取结果的函数实现。
https://github.com/aspectron/rusty-kaspa/blob/master/rpc/macros/src/wrpc/client.rs#L46
wRPC有一个call()函数,它接受Borsh可序列化的数据类型(与Opcode耦合)并返回反序列化的类型。
请注意,这是复杂的,所以任何人都会感到困惑是正常的。(客户端宏还解决了围绕这一点展开异步函数的问题,这让事情看起来非常混乱)。但如果你使用VSC,你可以使用“Rust Analyzer Expand Macro”,看看特性中的任何异步fn,看看引擎盖下到底发生了什么。但这是一个单独的问题。
这里的关键元素是跟踪/理解序列化是如何工作的,因为call()的参数及其返回值都是从所使用的数据类型中推断出来的。如果您有A和B,只要它们都实现BorshSerialize和serde::Serialize,如果您将A或B传递给call(),它将序列化适当的类型(反之亦然)
WASM:
https://github.com/aspectron/rusty-kaspa/blob/master/rpc/macros/src/wrpc/wasm.rs#L44-L92
RPC macros use this helper struct called Handler https://github.com/aspectron/rusty-kaspa/blob/master/rpc/macros/src/handler.rs
它使用一些Expr(动词),如Ping,并构建一个包含各种相关名称的结构,如PingRequest、PingResponse Ping_call等。
这些宏在trait impl内部使用。
然后,对于每个提供的条目【Ping、Shutdown、Ban】等,它实现如下功能: https://github.com/aspectron/rusty-kaspa/blob/master/rpc/macros/src/wrpc/wasm.rs#L84
So you give it Ping and the result is:
pub async fn ping_call(&self, request: IPingRequest) ->Result<PingResponse>
{
let request : PingRequest = IPingRequest.try_into()?;
let result = RpcResult<PingResponse> = self.inner.client.ping_call(request).await;
let response : PingResponse = result.map_err(|err| JsError::new(&err.to_string()))?;
Ok(response.try_into()?)
}
除此之外,所有请求/响应数据结构都具有自定义TryFrom声明(请求的TryFromJsValue和JsValue的TryOf-Response)。转换结构在这里实现:
https://github.com/aspectron/rusty-kaspa/blob/master/rpc/core/src/wasm/message.rs
macro宏是惊人的,但它们也有负面的一面,那就是它们隐藏了实现。人们需要制作一些来适应它们。
使用哪个IDE?在VSC中,我使用F12或Ctrl+单击来跳转到声明。这有助于导航。尽管TryFrom很难找到。无论如何,RPC有点像章鱼代码,因为它是跨多个板条箱分层的,以反映实际的数据结构(因为板条箱施加了结构依赖关系,而这些依赖关系最终被投影到绑定上)。
举个例子,事务处于较低级别,因为它是RPC所需要的,所以它的wasm绑定是一致的,然后使用它的RPC绑定在RPC中,然后钱包和顶层原语同时使用…
感动 | 同情 | 无聊 | 愤怒 | 搞笑 | 难过 | 高兴 | 路过 |
相关文章
-
没有相关内容