Skip to content

Commit 3613ad7

Browse files
author
yue.wang
committed
Update image links.
Signed-off-by: yue.wang <[email protected]>
1 parent 76ddf9b commit 3613ad7

File tree

1 file changed

+18
-18
lines changed

1 file changed

+18
-18
lines changed

docs/circuit_discussion_CN.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,29 @@
66

77
之前优化的想法是这样的,中间状态不验证,而只有block出入的merkle tree root进行验证。
88

9-
![image-20190723091104776](/Users/yueawang/Documents/My_Reports/loopring/images/check-status-at-the-end.png)
9+
![image-20190723091104776](https://user-images.githubusercontent.com/26989346/63236800-c133c800-c271-11e9-9109-81c77a01af3d.png)
1010

1111
该方案不可行是因为必须保证Merkle Path的一致性。如下图所示,本来Merkle Root验证电路本身比较简单,输入是path和leaf,输出是merkle root。
1212

13-
![image-20190722192752108](/Users/yueawang/Documents/My_Reports/loopring/images/merkle gadget.png)
13+
![image-20190722192752108](https://user-images.githubusercontent.com/26989346/63237004-c2192980-c272-11e9-914b-0812fac36025.png)
1414

1515
对于Loopring的电路设计,我们有before和after两个merkle tree需要被验证,于是有:
1616

17-
![image-20190722205208609](/Users/yueawang/Documents/My_Reports/loopring/images/before and after mkl gadget.png)
17+
![image-20190722205208609](https://user-images.githubusercontent.com/26989346/63237034-e2e17f00-c272-11e9-919d-afae29917f99.png)
1818

1919

2020

2121
这里有个问题,因为before和after完全没有联系,那么任意构造的merkle树都可以单独通过before或者after的验证,也就是说before和after可以来自完全不同的两颗merkle树,且各自符合merkle逻辑。所以为了保证内部的操作在同一棵merkle tree上完成,也就必须让before和after产生联系,目前看来只有这样一种方案,如下图所示:
2222

23-
![image-20190722205053165](/Users/yueawang/Documents/My_Reports/loopring/images/current deposit gadget link.png)
23+
![image-20190722205053165](https://user-images.githubusercontent.com/26989346/63237047-f0970480-c272-11e9-8d9f-b1cf30a50198.png)
2424

2525
即对before和after使用同一份merkle path做验证,这样保证了对节点状态的改动始终在同一棵merkle树上,但是此方案的副作用就是每次只能用来验证一个节点的一次改动,因为合并的多个节点的改动不可能有公用的merkle path。
2626

2727
2. 为什么需要sha256在电路的最后(这里指deposit/withdraw,ringsettle似乎没有这个计算),直接使用merkle root行不行?为什么合约还要计算sha256,直接拿statement行不行?如果合约不用计算的话,换个hash行不行?
2828

2929
答案都是不行,或者说当前设计下不行。首先看看当前的设计:
3030

31-
![image-20190722203724585](/Users/yueawang/Documents/My_Reports/loopring/images/circuit overview.png)
31+
![image-20190722203724585](https://user-images.githubusercontent.com/26989346/63237063-00aee400-c273-11e9-8685-8f7f8e80c223.png)
3232

3333
基本上有两块,上面一行是对merkle树的验证,下面一行是以block为单位的一个hash。可以对比以太坊来理解这个模型,上面一行depositGadget是对eth stateDB的操作,将每一个request对应到一个eth的tx,而下面这个sha256hash就是对应到eth block hash。
3434

@@ -48,9 +48,9 @@
4848

4949
下面两张图是eth的block内部两个主要数据结构tx_root和state_root的组织方式
5050

51-
![image-20190722231911683](/Users/yueawang/Documents/My_Reports/loopring/images/eth_tx_root.png)
51+
![image-20190722231911683](https://user-images.githubusercontent.com/26989346/63237087-13291d80-c273-11e9-8f9c-8951d9447c0c.png)
5252

53-
![image-20190722232012755](/Users/yueawang/Documents/My_Reports/loopring/images/eth_state_root.png)
53+
![image-20190722232012755](https://user-images.githubusercontent.com/26989346/63237106-2cca6500-c273-11e9-8404-2a48766f326e.png)
5454

5555
基本对应关系如下:
5656

@@ -71,13 +71,13 @@
7171

7272
## 2. OrderCancel电路笔记
7373

74-
![image-20190803160429976](/Users/yueawang/Documents/My_Reports/loopring/images/ordercancel character view.png)
74+
![image-20190803160429976](https://user-images.githubusercontent.com/26989346/63237118-3a7fea80-c273-11e9-88ba-cb482c303ea7.png)
7575

7676
###2.1 Input : output
7777

7878
​ 基本设置和DepositCircuit相同,输入是Cancelled Order Block的描述,输出是全部相关变量的hash,其实全部5种电路的设计都是一样的(虚线需要开启onChainData)
7979

80-
![image-20190803165832629](/Users/yueawang/Documents/My_Reports/loopring/images/ordercancel circuit top view.png)
80+
![image-20190803165832629](https://user-images.githubusercontent.com/26989346/63237549-11605980-c275-11e9-82ed-f016788b212d.png)
8181

8282
具体到代码是这样的:
8383

@@ -189,15 +189,15 @@ public:
189189

190190
1. Merkle验证电路是一系列updateXXX电路的主要组成部分,一次验证一个节点的改动
191191

192-
![image-20190731121508839](/Users/yueawang/Documents/My_Reports/loopring/images/merkle gadgets.png)
192+
![image-20190731121508839](https://user-images.githubusercontent.com/26989346/63238779-94d07980-c27a-11e9-963c-6591510ae323.png)
193193

194194
2. Fee Calculation
195195

196-
![image-20190731142721181](/Users/yueawang/Documents/My_Reports/loopring/images/fee calculation.png)
196+
![image-20190731142721181](https://user-images.githubusercontent.com/26989346/63238796-a6198600-c27a-11e9-885c-b9c07be597e8.png)
197197

198198
3. Balance Check
199199

200-
![image-20190731142036411](/Users/yueawang/Documents/My_Reports/loopring/images/balance check gadget.png)
200+
![image-20190731142036411](https://user-images.githubusercontent.com/26989346/63238834-d82ae800-c27a-11e9-9070-c51568d51468.png)
201201

202202
4. Poseidon Hash Gadget
203203

@@ -263,7 +263,7 @@ public:
263263

264264
难以理解的地方在于1p和2p。下面用设计图来说明该选择算法:
265265

266-
![image-20190803163045704](/Users/yueawang/Documents/My_Reports/loopring/images/4x path selector view.png)
266+
![image-20190803163045704](https://user-images.githubusercontent.com/26989346/63238850-f395f300-c27a-11e9-9df9-ea86c5a400cf.png)
267267

268268
左边表示的是4x树的path selector算法,对于child0来说,他只有input和sibling0两个选择,由于input和sibling信息都是顺序排列的,所以child0不可能选择sibling1,因此1bit信息(这里用的bit0 | bit1)就可以区分。而对于child1来说,他有3个选择,因此需要2bit的信息才能区分,同样的,child2也存在这个问题,而child3和child0一样,1bit信息足够。所以代码里面child0和child3不需要额外的处理,而child1和child2分别需要child1p和child2p(各自包含1bit信息)来区分他们走的那一条path。基于这个设计思路,我们可以比较容易(理论上)的构造一个8x的merkle path selector,如右图所示,很显然,我们要做的就是通过3个bit的信息,构造出child0, child1/1p, child2/2p, ..., child6/6p和child7。
269269

@@ -277,13 +277,13 @@ public:
277277

278278
他们之间的关系基本如下,未来不同的fee model可能有区别。
279279

280-
![image-20190802163217743](/Users/yueawang/Documents/My_Reports/loopring/images/ringsettlement characters view.png)
280+
![image-20190802163217743](https://user-images.githubusercontent.com/26989346/63238877-0c060d80-c27b-11e9-906b-82a62e4a4ed4.png)
281281

282282
### 3.2 基本逻辑
283283

284284
电路的基本逻辑和之前的Deposit,OrderCancel一样,输入是RingSettlementBlock,输出是一批publicData的hash值,中间电路由若干RingSettlementGadget组成,加上一批外围验证的逻辑,top level框图如下,可以看到电路的基本设计是一致的:
285285

286-
![image-20190801221206000](/Users/yueawang/Documents/My_Reports/loopring/images/ringsettlement_top_view.png)
286+
![image-20190801221206000](https://user-images.githubusercontent.com/26989346/63238893-1cb68380-c27b-11e9-9ee8-f78e10c2e626.png)
287287

288288
中间有些value需要开启onchainDataAvailable才会加入到hash计算中,因此用虚线标注,但不影响整体逻辑。
289289

@@ -377,7 +377,7 @@ class RingSettlementBlock
377377

378378
关系如下:
379379

380-
![image-20190801223937621](/Users/yueawang/Documents/My_Reports/loopring/images/ring_backend_class_view.png)
380+
![image-20190801223937621](https://user-images.githubusercontent.com/26989346/63239054-e62d3880-c27b-11e9-890e-22faa97f3659.png)
381381

382382
其中RingSettlementBlock作为RingSettlementCircuit电路的输入,其中主要部分RingSettlementGadget就是在验证对RingSettlement的操作是否有效。RingSettleGadget的声明(部分)如下,显然是在验证RingSettlement的计算。
383383

@@ -519,7 +519,7 @@ public:
519519
520520
这里注意每一个transfer电路都会去拿这些balance的最新的值,即balanceX_X.back(),然后每个电路的输出会把输出(也就是新的值的variableT)push_back()到这个vector里面去。注意这里其实并不是动态的挑选variable,因为每个电路的输出都是预先定义好的,理论上只要仔细加上命名合理,全部用中间的out结果是没问题的。但是这样做在代码的组织上就比较好看了,是一个值得学习的小技巧。基本的逻辑如下所示:
521521
522-
![image-20190802175614989](/Users/yueawang/Documents/My_Reports/loopring/images/dynamic_variables.png)
522+
![image-20190802175614989](https://user-images.githubusercontent.com/26989346/63238909-31931700-c27b-11e9-893d-efc6db991d9e.png)
523523
524524
当然直接拿这些中间电路的out variable是一样的,比如OrderCancel电路里面计算fee的时候就没有用这个技巧,应该是因为那边计算的级数没有这里多,所以改善代码的意义不大。
525525
@@ -539,6 +539,6 @@ public:
539539
9 TransferGadget ringFee_from_balanceOM_to_balanceO;
540540
```
541541

542-
![image-20190802163757644](/Users/yueawang/Documents/My_Reports/loopring/images/ring transfer sequence.png)
542+
![image-20190802163757644](https://user-images.githubusercontent.com/26989346/63238920-440d5080-c27b-11e9-8b13-def16e077235.png)
543543

544544

0 commit comments

Comments
 (0)