发新帖

Celer network:将互联网应用大规模带入区块链世界

admin 5月前 77080

这一波的主角是Celer network,Celer是拉丁文,意思是快速的,c也就是在物理中代表真空中的光速就是来源于这个词的名词形式(celeritas:速度)的首字母。

Celer的目标是用链下交易技术闯出一片新天地,支持十亿(Billions)数量级的TPS。做法之一就是想办法把链上的多搬一点到链下去,Liquidity也表示出了这个趋势(当然关键的地方诸如链下合约什么的Liquidity啥都没说)。此外Celer也没有给出像闪电网络那么深入的细节,不过总体还是比Liquidity给的料要多很多。Celer中有意思的点有这么几个:通用的带条件的链下状态通道,链下分层架构,跨通道存款再分配,带通道平衡的高效支付路由,以及解决全网流动性的token economy机制。下面逐一来看下:

1. 允许更通用的条件支付通道

之前的闪电网络,雷电网络都是着眼于链下的简单支付(也就是A愿意支付钱给B,至少在系统看来是无条件的支付),从而试图减少主链的负担。但是他们太深入Blockchain 1.0的简单支付了,似乎多少忘了2.0时代的smart contract。我们一直说smart contract的存在使得很多人为的条件判断和仲裁都见鬼去了,所以理所当然带条件的支付也可以挪到链下支持,比如A和B对赌,谁赢了就拿到对方的钱,这在链上合约中已经很常见了,链下的话之前并不多。

Celer中最基本的状态通道依旧是两人之间的双向支付连接,需要将存款存入主链来创建通道,然后依赖于类似闪电网络RSMC的可更新合约作为链下支付状态来约束双方,同时也能作为通道的状态。具体来说,一个存在于Alice和Bob之间的支付通道的状态由以下元素来构成:

Alice的当前余额

Bob的当前余额

Alice的签名

Bob的签名

通道内当前状态的序列号(Sequence number, 单调递增,最高的序列号代表当前最新的有效状态)

两人之间已创建但还未结算完的支付。每笔支付指定了支付人,收款人,支付金额和触发支付的条件。

以下是栗子时间:

一开始,Alice链上存了100 ETH,Bob存入50 ETH。在创建了通道后,当前的状态就是:

状态1: 100 | 50 | Alice签名 | Bob签名 | seq1 | 无任何未结算支付

然后,Alice打算和Bob玩个小“游戏”,谁下棋赢了就付给对方5 ETH。这里输赢结果需要是可验证的自于链上的状态。于是Alice会创建以下状态并进行签名。

状态2: 100 | 50 | Alice签名 | 空 | seq2 | 一对未结算的支付。支付1: 如果Bob赢了,Alice付给Bob 5 ETH;支付2: 如果Alice赢了,Bob付给Alice 5 ETH。需要Bob在时间点T之前对支付进行签名。

Bob接受后进行签名,于是变成

状态2':100 | 50 | Alice签名 | Bob签名 | seq2 | 一对未结算支付

假设Bob赢了,Bob会发起状态更新,即链下支付行为

状态3: 100 - 5 | 50 + 5 | 空 | Bob签名 | seq3 | 无未结算支付

Alice愿赌服输后,进行签字,于是:

状态3': 95 | 55 | Alice签名 | Bob签名 | seq3 | 无未结算支付

如果Alice不愿签名,则Bob可以发起链上纠纷仲裁,并且提供所有以上的支付历史(通道的状态历史)并且在链上可以被验证的条件。

以上的流程虽然比我之前想象中的要更加“手动”一些,而且看起来只是比闪电网络等等增加"状态2"和"状态2'",不过将通道如此通用化看起来还是很舒服的,总体还是又进了一步。此外如前文所说,Celer这里并没有像闪电网络那样具体说明了怎么通过不同的密钥签名来作废之前的支付或状态,防止有一方耍赖将对自己有利的旧的余额分配进行上链兑现。

2. 链下分层架构

从上一点推演而来就是可以站在更高处看待链下交易,即:链下交易并不是链上的一个简单附庸,而是一个独立的世界,其实可以有自己的具体架构和层级,并且可以选择将链下体系应用在不同的主链上。Celer给出的分层架构极大程度上借鉴了互联网分层协议模型,看起来还是满贴合的。

从最底层开始,第一层是Celer通道层,对应的是TCP/IP模型中的网络接口层,基本的作用提供链上和链下的过渡和连接,负责两两之间的通道创建和管理,并且将实实在在发生链上交易的主区块链进行抽象和隐藏,从而可以应对各种不同的实际区块链作为自己的底层宿主。就像互联网的网络接口层那样提供与实际物理硬件之间的接口,以保证上层协议不用关心纷杂的底层细节。当然具体怎么实现各种主链的支持Celer并没有交代太多。

往上是Celer路由层,正好对应的就是网络层,即众所周知的IP协议。职责也几乎一样,就是维护一个实际的网络拓扑结构,主要解决最佳路由选择,拥塞控制和网络互联的问题。而且将Celer路由层单独区分出来的好处就是可以仿照互联网网络层那样支持将某一个支付进行拆分后分开进行路由和传达,甚至每个拆分下来的碎片可以走不同的路径, 类似于一个端到端的信息可以实际拆分出多个IP数据报(datagram)一样。这大概就是建模站在巨人肩膀上的威力了,很自然就推导出了这么个不得了的feature。

第三层是Celer传输层,也就对应传输层,TCP协议和UDP协议应该都了解过了吧。两层的作用也是相似度极高,负责的将下层路由层的数据进行收集处理,完成一个端到端(End-to-end)的可靠支付处理,对上层封装了具体的节点间的路由细节,并对上层提供了通用接口,于是上层只需要关心支付的起点和终点即可。正如TCP需要保证消息顺序以及可靠性到达,Celer的传输层需要能够保证被拆分了的支付在终点的完整性和可靠性到达。Celer也把这层说成了是操作系统OS,这个视角是从本层承载和驱动了上层应用层里的程序而言的,虽然fancy但感觉不本质,还是按照网路模型的传输层理解更加清晰。

最上层是Celer应用层,对应的是应用层,只不过互联网中的应用层里除了实际的应用程序还有各种五花八门的应用功能协议,比如HTTP,FTP等,而Celer这里则只是包括了调用传输层接口的应用程序。本层的好处需要结合封装良好的输出层,可以允许第三方应用程序的开发更加方便和直观,从而提升开发者的开发体验和终端用户的使用体验。

这四层的逻辑还是挺清楚易懂的,就不做小结了。

3. 存款再分配

本系列第二篇中我们提到过Liquidity的REVIVE模型给出了通过线性规划在一个形成环状的通道网络间进行存款调度。需要多人间形成环状的两两连接的要求比较高,在实际动态复杂的链下交易网络中并不能作为一个稳定的通用方案。

还有一种办法是类似Liquidty这样的支持多人间交互的通道,不过这样会有单点失败的风险,并且也存在性能瓶颈。所以Celer还是倾向于双人间双向通道,并且对上述多人间通道模型做了改良,变成了一个星形结构(由中心点连接周围其他点)的多人通道,具体做法是让某个节点比如Alice拉上其他与自己存在直接相连的邻居节点们Bob,Coral,Dave们一起搞个多人间通道,Alice就是中心点,是主导人。Alice可以通过一个特别的链上交易将币存入这个通道里,并且在其他节点之间分配存款(也需要其他邻居节点的签名),比如这个交易可以长成这样:

存款轮次/序号: DR1

A分配给AB通道:40 ETH

A给AC通道:10 ETH

A给AD通道:50 ETH

如果接着之前第一个栗子的话,这个时候Alice和Bob之间的支付通道的最新状态就可以是:

状态4: 95 | 55 | Alice签名 | Bob签名 | seq4 | 无未结算支付 | DR1

实际效果等同于

状态4': 95 + 40 | 55 | Alice签名 | Bob签名 | seq4 | 无未结算支付

这里的存款分配可以被不停更新,每次更新需要再来一次特殊交易,产生递增的存款轮次,然后通道状态中只认最高存款轮次对应的分配方案。

以上的调整方案的好处是,当出现通道内金额不够的时候时,不用像闪电网络那样只好关闭现有的两人间通道,预存足够的金额再通过链上交易开一个通道,而是借助每个节点产生的多人间星状通道来保持其他现存的两人间通道的金额调度。但是也有问题,就是每次存款调度都会产生一个新的链上交易,所以只适合低频的偶尔为之的再分配。

所以除了上述改良方法之外,Celer还给出了另外一个办法,是一个更高频的在正常的支付活动中就会自动进行再平衡的方案,我们在下一个章节再详细说,

4. 基于拥堵梯度的路由策略

目前基于两人通道间的路由策略大部分都是原始粗暴的、考虑了通道内可转金额上限的最短路径算法或者其改良版本,这样就产生了问题:大部分场景下的支付都是单向的(就算是两个不同货币间的原子互换看起来是双向支付,对于具体的某个货币而言也还是单向的),于是token在不同通道间无脑的转着转着就会出现通道内金额极度不平衡的状态。

比如一个A、C和C的三角关系中(存在双向通道AB,BC,AC),每个通道内每一方都有100 ETH(下面左图),如果这个时候我们发起一波连锁支付:A给B 100, B给C 100, C给A 100,那么无脑的最短路径支付就会导致下面右图的情况,即每个通道内都是0 : 200的状态。

如果我们假设“A给B 100”,“B给C 100”还是直接发生他们各自支付通道中(入下面左图)。但是让C绕个远路,通过B做中间人转给A 100(下面右图),那么我们就会发现AC通道自始至终没有被使用过,而经由CB和BA通道内的C到A的转账使得三个通道还是100 : 100的平衡状态。

由此观察,我们可以发现最短路径会需要更频繁的通道内余额再分配再平衡,不是很理想。这里比较理想的是存在更加聪明的支付路由机制,可以像上面C到B到A那样另辟蹊径,在完成支付的同时保障了通道两头金额的平衡。这里的难点在于因为整个网络环境是去中心化的分布式的,所以不存在一个全局优化的办法,只能通过局部优化来影响全局。 Celer受到了无线网络中的堵塞梯度(congestion gradients)的启示,具体来说是背路由算法(具体后面会涉及),将梯度网络的一套概念用到了支付网络中。

这里先来看下几个概念。梯度(Gradients)的概念大家应该在高数微积分里有学过,它在机器学习ML和数字图像处理中有着广泛的应用,比较常见的可能就是梯度下降法(Gradient descent)了。具体来说,假设一个三维的山坡的函数 H(x, y),那么点(x0, y0)所在的高度z0 = H(x0, y0)。这时,在点(x0, y0)上的梯度的几何含义就是整个山体在该点坡度最陡的方向(投射到xy平面);在数学上表达为H(x,y)分别在x和y方向上的一阶偏导数所组成的一个二维向量(在xy数轴组成的二纬平面上),该向量所指的方向就是函数值z变化最快的方向。下图中的黑线就是从山顶处某起点下坡到山脚最快的路径,也就是一路上梯度给出的方向指引,换句话说,如果有一条河流从该起点出发,那么他在重力势能的引导下必然会选择这条最快路径。当然用三维山体的栗子只是因为方便理解,实际上更多情况下梯度都是扩展到多元函数和多维空间来做具体应用的。

知道梯度后再来看下梯度网络(Gradient neetwork)和拥堵(Congestion),这些都是十几年前年提出的概念了。梯度网络是在无向(双向也行吧)的基底网络之上的一个或多个有向子网络,在这个子网络中,其中每个节点都具有1)标量数值(scalar)作为势能,和 2)仅仅一条指向其相邻节点中具有最小(或最大)势能的那个节点的外向链接。下图中带箭头的边连起来的子网就是梯度网络,再加上没有箭头的边就是原来的基底网络。

在该网络模型中,每个节点的势能会随着时间或其他因素而改变,所以梯度网络的拓扑结果也会随之动态改变。这个梯度网络可以对复杂的网络中的物质流动(flow),甚至最速流动进行建模和研究。比如大型电网里的电流,复杂水道网中的水流,这种都有自然的电势和重力势能作为标量数值在一直影响网络中的物质流动。学过物理的都知道电势差可以产生和影响电流(即电子的流动),而且他们都很会“偷懒”,一定会走最轻松的、势能差最大、阻力最小的路径,换言之,局部梯度(gradient)产生流动(flow),又称梯度流(gradient flow)。而大型复杂网络内的车流,物流,数据信息流,以及支付的路由和规划也是如此,只是这里的势能可以通过人为定义,进而指定了每个节点基于相邻节点的势能后选择如何转移发送“物质”的局部行为规则(其实有点感觉和讲《NKN》时说的元胞自动机的想法差不多,都是通过局部动态变化来使得整体系统进化和成长)。

而拥堵讲的是如果网络是星状的,那么中间节点可能会需要处理来自周边节点的流,从而流会有在中心点处发生堵塞,于是就有了一个拥堵因子(jamming factor)的定义,假设有一条流经过n个节点,接受这条流的节点被称作接受节点,将这条流发送到他处的节点是发送节点,前者节点的个数成为接受节点数,后者是发送节点数,那么堵塞因子 J 差不多是: 1 - (接受节点数 / 发送节点数),J为0时表示畅通无阻,J为1表示完全堵塞。所以可以看出堵塞与否和接受流的节点数量关系密切。另外由于绝大多觉情况下,节点处理流是要花费时间的,所以拥堵也会造成工作队列长度的增加。

上述是一些基础知识,Celer借鉴的模型跑在一个拥堵梯度网络,也就是将拥堵程度作为节点的“势能”,来影响每个局部节点对于某个具体支付的发送路径选择,于是路由完成的同时也完成了余额再调整。具体来说,Celer是这么定义了他的模型的:

4.1 首先,定义token转移流(token transfer flow,可能叫支付流更为方便)k是某条由具体起点(源节点)和终点(目的节点)决定的唯一支付路径(端到端)。在某一时刻t的开头,某节点i为流经它的某支付流 k维护了一个债队列(debt queue),标记为Q(i, t, k),这个债队列也就是该节点需要在下一跳中转出去的token总数(但是在t时刻刚开的时候还没有来得及能转出去),算是衡量拥堵的标量。那么对于同一条支付流k,在t的下一时刻也就是t+1时刻的开头,

节点i的债队列Q(i, t + 1, k) = Q(i, t, k) + t时刻需要节点i完成的新的支付所涉及到的token + 节点i的邻居节点们转给i的token - 节点i转出去给邻居们的token。

“t时刻需要节点i完成的新的支付所涉及到的token”按字面意思看意思很显然。而“节点i的邻居们转给i的token”就是节点i收到的“击鼓传花”中的“烫手山芋”,“节点i转出去给他的邻居们的token”是节点i已经送出去的“山芋”。此外,终点节点上的债队列永远为零(只进不出,永不欠谁)。

4.2 然后定义在时刻t下,两个节点i和j之间通道的金额平衡失调度,

痛到失调度 ∆(i, j, t) = 节点j转给i的token - 节点i转给j的token(算上t时刻前的所有时刻中,每条经过这个通道的流所引发的所有token转移)。

如果∆(i, j, t) < 0,代表节点i转给j的token超过j给i的。等于零的话,表示出入相当,通道平衡。

4.3 根据背压(BackPressure)路由算法定义了背压权重(BackPressure weight)。其实这里“背压”应该翻译成逆压或反压更贴切,该词来源于工程中气流或液流由于管道突然变细、急弯等原因导致由某处出现了下游向上游的逆向压力,不过翻译中把back翻成了“背部”,也就这么流传了下来。

“背压路由算法”则是专门用来研究了在基于工作队列的多跳网络中使用拥堵梯度来动态规划路由,并且对时间进行了时隙(time slot)分割,力求在时隙推进过程中减少网络中的队列积压(queue backlog),主要应用在无线网络中,移动ad hoc网络中等,是Celer路由层中主要借鉴的算法模型。之前Celer已经准备好了债队列可以作为背压算法中的队列直接套公式,而通道失调度只是作为 一个额外的考虑因素。以下是定义:

背压权重 W(i, j, t, k)= [ Q(i, t, k) - Q(j, t, k) ] + β * ∆(i, j, t), 其中β是通道失调度的影响力因子。

上方方括号内则是节点i和j之间的差异积压(differential backlog)。背压路由算法的目标就是在每个时间段都寻求在一众相邻节点间差异积压最大(即拥堵梯度)的方向上(即:该节点对之间)进行路由转移,就像之前说的梯度网络中的流动模式一样,从而减少节点i处的拥堵。

对Celer来说,具体的局部路由算法就是:

节点i不停获取相邻节点的债队列的信息。

节点i和相邻节点建立的两两之间的通道会经过多条不同的支付流。

然后在每个时间段中,节点i会计算在每个通道上产生最大背压权重的那条支付流,并且在该通道上进行该特定支付流的token转移发送。而这个路由算法要解决的就是一个叫做MaxWeight的优化问题(包括一个很显然的约束即:支付量不能超过通道的能力范围)。

Celer的实验表示这套路由算法引入支付网络后炸了,比闪电网络之类的路由性能提高了15倍,由于通道内两头的金额和支付更加平衡,各个通道的利用率提高了20倍。

5. 通证经济激励

这块和技术关联不大,我就很快带过了。主要值得一提的是这里想解决的是链下交易的另一大问题:资金流动性。Celer给出了一个办法就是允许支付服务提供商通过发布借债拍卖合约来向大众举短期债,从而获得融资获得流动性。拍卖提供信息诸如需要多少钱,借多久,最大利息肯给多少。而对于参与竞拍的每个竞标,都会有一套机制对他们进行打分(所要利息高低,借出金额大小,锁入的celer本币CLR的多寡),分数依次最高的一个或多个竞标则会中标。 这里竞标人愿意锁入的CLR如果足够多,就算要求最高利息,得分也会名列前茅(给本币后门开的有点大啊),另外引入了借据(IOU)而不是将实际募得的资金直接打给举债人,以增加安全性。另一方面,Celer还鼓励大家把虚拟资产进行长期锁定(锁入“抵押承诺合约”)来支持Celer网络流动性,等于是一种PoS挖矿,能够获得CLR。

总的来看,Celer思路还是很清晰的,目前看来比Liquidity的强度高不少(话说Liquidity就做出了这么个破demo有什么好对Celer叫板的,谁给你的勇气),另外团队学术背景相当牛叉。这里如果不谈链下产业的整体价值和意义,而直接对Celer项目本身做nitpick的话,就是链下通道状态的一致性和安全性的细节上并没有像闪电网络那样完全给出,另外有的环节比如带条件支付貌似并没想象中那么fancy,cOS包装的稍微有点过了。此外,可能看下来有人会觉得Celer在几个大创新点上比如分层架构和路由算法都比较多地借鉴了其他领域现成的想法和成果,其实这点没什么毛病,本来CS领域中对于实际问题进行建模的目的之一就是理清思路,然后试着找寻已有的或者接近的模型、解决方案或最佳实践,能找到的话自然就不用再造一次轮子了,就像NKN引入元胞自动机,各个项目引入分片一样的道理,有时候贵在拥有广博的知识以及一双慧眼。

最新回复 (0)
返回
发新帖
admin
主题数
219
帖子数
0
注册排名
1