您现在的位置:kastop>> Kas信息 Kaspa网络>>正文内容

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中,然后钱包和顶层原语同时使用…


感动 同情 无聊 愤怒 搞笑 难过 高兴 路过
【字体: 】【收藏】【打印文章】 【 打赏 】 【查看评论

相关文章

    没有相关内容