本文描述了dingir-exchange如何处理交易流程:以tradejs为例
背景
1、关于 dingir-exchange
官方描述是基于Rust语言开发的交易所,更具体的可以看具体的官方文档1。
2、为什么学习它
1)对Rust语言感兴趣,并且做过基于Rust的服务端开源项目。
2)该项目处于相对初级阶段,想从头跟一下别人的工作方法。
工程模块简介2
.
├── Cargo.lock #Cargo自动生成的文件不需要修改。(为什么不添加到.gitignore中?)
├── Cargo.toml #工程配置文件,包括基本信息、依赖、特性等
├── Makefile #Makefile文件
├── README.md #说明
├── build.rs #自定义构建流程用
├── config.yaml #一些配置信息
├── docker #包含docker相关的配置文件
├── examples #例子,包含了该文用到的trade.js
├── migrations #sql
├── proto #包含matchengine.proto
├── rust-toolchain #rust-toolchain
├── rustfmt.toml #rustfmt.toml
├── scripts #安装该工程的依赖shell脚本
├── src #源码所在的文件夹
└── target #rust编译输出文件夹。(添加大了.gitigore中)
对于该文来说,主要聚焦在2个目录中,examples和src,其他相关的文件不作为重点考虑。
-建议
1、Cargo.lock 可以添加到 .gitignore 中。
2、既然是开源的项目,其实应该加上License。
examples & src
examples - trade.js
example是基于JavaScript实现的,不难理解,去掉无关紧要的代码,该文件的代码可以简化为
async function main() {
const askOrder = await orderPut(
userId,
market,
ORDER_SIDE_ASK,
ORDER_TYPE_LIMIT,
/*amount*/ "4",
/*price*/ "1.1",
fee,
fee
);
const bidOrder = await orderPut(
userId,
market,
ORDER_SIDE_BID,
ORDER_TYPE_LIMIT,
/*amount*/ "10",
/*price*/ "1.1",
fee,
fee
);
return [askOrder.id, bidOrder.id];
}
就是撮合 askOrder 和 bidOrder,其中 orderPut
是引自 client.mjs
的方法,mjs 表示该文件是JavaScript的一个模块,可参考文章3关于JavaScript模块的介绍。
examples - client.mjs
关于 orderPut
方法,直接调用了 client 的 OrderPut 方法,参数进行了透传,其中 client 定义如下:
const client = caller(`${server}`, { file, load }, "Matchengine");
caller 为 import caller from "@eeston/grpc-caller"
。 grpc-caller
是JavaScript版本的 gRPC 客户端,详细用法见4介绍。
matchengine.proto
OrderPut
声明如下
rpc OrderPut(OrderPutRequest) returns (OrderInfo) {
option (google.api.http) = {
post : "/order"
body : "*"
};
}
src
src - server.rs - order_put
简化后的实现,主要是调用了 controller
中的 order_put 方法:
async fn order_put(&self, request: Request<OrderPutRequest>) -> Result<Response<OrderInfo>, Status> {
ctrl.order_put(true, request.into_inner())
}
src - controller - order_put
这里的主要实现就是调用 market
的 order_put 。
pub fn order_put(&mut self, real: bool, req: OrderPutRequest) -> Result<OrderInfo, Status> {
let order = market
.put_order(&mut self.sequencer, balance_manager.into(), persistor, order_input)
.map_err(|e| Status::unknown(format!("{}", e)))?;
}
src - market - order_put
该方法主要是对 order 的处理,调用真正的撮合方法 execute_order
self.execute_order(sequencer, &mut balance_manager, &mut persistor, order, "e_limit);
到此,交易撮合完成。
-
鉴于项目后期会重构,本文所描述的代码都是基于 2021-5-28 日最后提交。 ↩