Gavin Wood:深入研究XCM底层设计和执行模型

麦斯财经 140 0
Gavin Wood:深入研究XCM底层设计和执行模型

              


作为波卡生态共识系统之间交流思想的言语,XCM的主要性不容分说。在《Gavin Wood:详解跨共识音讯格式XCM设计原理与运转机制》一文中,Gavin Wood关于XCM设计原理与运转机制中止了十分精细的解说。而在《Gavin Wood:探求XCM的版本掌握与兼容性》一文中,Gavin Wood又对其版本掌握与兼容性中止了深化探求。接下去在本文中,Gavin Wood将会就XCM底层设计和施行模型来中止深化研讨,以辅佐自己更有效的了解XCM的底层虚拟机。作者:Gavin Wood根源:Polkadot编译:陈一晚风由于XCM是基于XCVM的指令集,而XCVM是一个十分初级的虚拟机,为了熟习这种机器架构,所以我们先来冗杂引见一下XCVM。XCVM是一个非常初级的、非图灵完备的虚拟机。它是基于寄存器而不是基于堆栈,并且有几个公用寄存器,其中大局部存储高度结构化的数据。与通用途理器不同,XCVM的存放器不能随意设置为恣意值,但有严酷的机制来掌握它们如何改动。除了与外地链外形交互的某些方式(例如我们曾经看到的WithdrawAsset和DepositAsset指令)之外,没有额外的“内存”。没有循环的可以性,也没有清楚的分支指令。在之前的文章中我们曾经引见了Holding Register和Origin Register两种存放器。Holding Register可以暂时持有一个或多个资产,并且可以经过从外地链中提取资产来填充,大约经过从受怀疑的外部接收资产来填充根源(例如另一个链);Origin Register在施行末尾时持有以后XCM施行根源的共识系统的位置,并且可以只能突变到一个外部位置或完整消除。而在在其他寄存器中,三个与非常/过失管理相关,两个与跟踪执行权重相关。我们将在本文中重点解说这些寄存器的执行模型。执行模型如前所述,没有显式条件指令或循环原语能够重复执行同一条指令屡次。这使得预先肯定次第的控制流变得相当冗杂。这个属性很有用,由于我们想要肯定XCM 息在执行点之前可以运用几执行时间(在整个Substrate/Polkadot中称为权重)。我们希冀执行XCM的大少数共识平台都需求可以在末尾执行之前肯定最坏状况的执行时间。这是由于区块链一般需求确保单个块的处置时间不会逾越某个预定限制,以免招致整个零碎停顿。此外,假定系统需求支付费用,那么它必需发生在支付费用的义务负载之前,而且这一领取必需涵盖最坏状况下的执行时间。由于这种图灵完备性,允许运用图灵完备言语的系统(例如以太坊)实际上无法直接从次第中计算出最坏状况的执行时间。他们经过央求用户预先肯定顺序的执行资源,然后在执行时计量并在逾越支付的数量时中缀它来处置这个效果。有时买卖会在买卖执行之前就发生变化,且权重变得不准确。令人快乐的是,像XCVM这样的非图灵齐备的虚拟机可以防止这种计量和权重规则的需求。权重权重一般表示为一个有代表性的硬件执行给定操作所需求的皮秒的整数。正如我们在BuyExecution指令中看到的那样,XCVM在处置某些指令时包括了执行时间/权重的概念。没有权重计量,但为了允许XCVM顺序最终取的权重小于最坏情况的权重预测,我们有一个称为盈余权重寄存器的寄存器。由于我们可以准确地预测它们会运用几权重,所以大少数说明书都不会触及它。但是,偶然会出现最坏情况权重预测高估的情况,只需在执行时我们才知道有几。在计算高估了XCM音讯权重的块执行时间时,跟踪原始权重被高估的数量,并从账户中减去它,允许链优化其块执行时间配额。因此,盈余权重寄存器关于我们的块执行时间核算很有用,但它并不能独自处置另一个效果,即确保所支付的金额不会被高估。为此,我们需求一个与BuyExecution相关的指令,它该指令将收取多余权重并退款。自然,这条指令是具有的,叫做“退款亏损”。它运用的第二个寄存器称为“退款权重寄存器”,以确保不会屡次退款相同的盈余权重。流量控制和非常到目前为止,还有两个寄存器在我们对XCVM的处置中相当含蓄,但依然很主要。首先是顺序寄存器,用于存储以后正在执行的XCVM程序。其次是程序计数器,它存储当前正在执行的指令索引。当程序寄存器改动时,它被重置为零,并在每个胜利执行的指令终了时加1。处置“非常”情况能够性的才干关于编写干练的代码至关主要。当远程系统上发生了你没故预料到(或确实无法预料到)的事情时,你就需要某种方式来管理它,即使它只是冗杂地向原始外形发送一个演讲。固然XCVM指令集不包括任何清楚的通用分支指令,但它的执行模型中确实有一个通用的非常处置框架。XCVM包括另外两个代码寄存器,每个寄存器都保管一个XCVM程序,如程序寄存器。这两个寄存器称为附录寄存器和过失处理程序寄存器。假定你熟习几种流行言语中的try/catch/finally非常系统,那么接下去的方式能够会让你冗杂了解。如前所述,XCVM程序的执行是依照其中的每条指令一步一步执行的。当它遵照这些指令到程序终了时,会发生以下两种情况之一:要么胜利抵达程序末尾,要么发生过失。在第一个成功执行的情况下,过失寄存器被消除,它的权重被增加到盈余权重寄存器。附录寄存器也被肃清,其方式被放置在程序寄存器中。假设程序寄存器为空,则中止,否则程序计数器复位为零。简而言之,我们抛出以后的程序和过失处理程序,假设有的话就末尾执行附录程序。此功用自身并不是很有用,但与发生过失时发生的情况相区分时会很有用。在这里,尚未执行的任何指令的权重都被增加到盈余权重寄存器中。错误处理程序寄存器被肃清,其形式放置在程序寄存器中,程序计数器复位为零。繁杂地说,我们抛出当前程序并末尾执行错误处理程序。由于我们没有肃清附录寄存器,所以除非它被错误处理程序重置,否则它会在成功完成后执行。由于其组合结构,它容许错误处理程序的恣意“嵌套”:假如需要,错误处理程序也可以有错误处理程序,附录可以有自己的附录。有两条指令容许操作这些寄存器:SetAppendix和SetErrorHandler.。前者设置附录寄存器,后者设置错误处理程序寄存器。其中每一个的预测权重都比其参数的权重略高。但是,当执行时,寄存器中将被交流的XCM音讯的权重被添加到盈余权重寄存器中,从而容许回收任何未使用的附录或错误处理程序的权重。投掷错误有时,确保错误发生并自定义错误的某些方面能够是有用的。这已经在编写测试代码时使用,但它最终能够会在活动链中找到使用。这这可以经过指令Trap在XCVM中完成,该指令总是招致错误发生。抛出的错误类型共享称号Trap。指令和错误都照应一个整数参数,答应在错误抛出者和外部观察者之间传递某种方式的消息。这是一个复杂的例子:Trap招致最终的DepositAsset被跳过,而错误处理程序的DepositAsset被运转,将 1 DOT(减去执行利息)置于平行链2000的一切权下。我们将一直倾向于RefundSurplus在错误处理程序代码的扫尾使用,由于如果它是运转,我们知道很能够使用的预测权重(以及因此置办的权重)是高估的。错误演讲能够引入处理错误的代码是非常有用的,但其中经常被央求使用的功用是能够将XCM消息的结果演讲给原始发送者。QueryResponse指令允许一个共识系统向另一个系统演讲一些消息,剩下的就是能够以某种方式将XCM的结果插入其中QueryResponse并将其发送给希冀原告知的人结果。梦想证明,只需一个指令完成了这个权益,它叫ReportError。它通过使用我们尚未遇到的寄存器来义务:错误寄存器。错误寄存器是一种可选类型(可以设置或清除)。如果已设置,则它包括两条消息:数字索引和XCM错误类型。它具有极端复杂的操作机制。首先,每当指令招致错误时,它总是被设置;错误类型设置为该错误的类型,数字索引设置为程序计数器寄存器的值。其次,只要当ClearError指令被执行时它才被清除。该指令是相对牢靠的指令之一,因为它自身永世不会招致错误。它在发生错误时被设置,并在你收回妥当的指令时被清除。往常应当可以清楚地了解ReportError指令是如何任务的:它只是QueryResponse使用错误寄存器的形式组成一条指令并将其发送到特定手腕地。当然,在它之前发生的任何错误都会招致指令被跳过,因为执行首先跳转到错误处理程序寄存器的代码,然后跳转到附录寄存器的代码。但是,处理这个效果的方法很简单:将reportterror放在附录中将确保它被执行,而不论主代码能否导致执行错误。我们来看一个简单的例子。我们会将资产(1 DOT)从中继链传送到Statemint(平行链 1000),在那里置办一些执行时间,然后使用Statemint作为贮藏,我们将资产取出平行链 2000。原始(非错误报告) ) 消息如下所示:有了基本的错误报告,我们将改为使用这个:正如你所看到的,独一的变化是引入了两条SetAppendix指令,以确保 Statemint 战争行链 2000中的错误或缺失将报告给中继链。这假定中继链已将自身设置为能够识别和处理来自Statemint和parchain 2000的QueryResponse消息,查询ID为42,权重限制为1000万。令人快乐的是,这确实是Substrate很好的支持,但往常已经超出了范围。资产圈套当在处理资产的程序中发生错误时(大少数情况下都是这样,因为它们经常需要为执行BuyExecution支付费用)),那么效果就会很大。能够具有BuyExecution指令本身导致错误的情况,可能是因为权重限制不准确或用于支付的资产缺少。大约,资产可能被发送到一条无法以有用的方式处理它的链上。在这些情况下,息的XCVM执行终了时资产仍留在Holding Register中,与其他寄存器一样,这些资产是瞬态的,我们希冀被遗忘。团队和他们的用户会很高兴晓得,Substrate的XCM允许链完整防止这种丧失。该机制分两步任务。首先,当Holding Register中的任何资产被清除时,都不会被完整遗忘。如果在XCVM中止时Holding Register不为空,则收回一个包括三个消息的事情:Holding Register的值;Origin Register的原始价值;以及这两条信息的哈希值。Substrate的XCM系统然后将这个哈希值放在存储中。这局部机制称为资产圈套。理赔系统该机制的第二步是能够央求Holding Register的一些先前形式。这实际上不是通过任何特地为此手腕而设计的,而是通过我们尚未遇到的通用指令ClaimAsset.这是它在《Rust》中的声明方式:此指令的称号可能让人想起我们遇到的某些其他“资助”指令,例如WithdrawAsset和ReceiveTeleportedAsset。与其他方法一样,它试图将资产(由assets此处的参数给出)放入Holding Registe。与WithdrawAsset添加账户链上资产余额的不同,不论Origin Register的值是几,都会为这些资产ClaimAsset寻觅有效的索赔。为了辅佐系统找到无效的索赔,可以通过ticket参数提供信息。如果找到无效的索赔,则将其从链中删除,并将资产添加到Holding Register中。往常,什么形成索赔完整取决于链本身。不同的链可能支持不同种类的央求,Substrate允许你冷静组合它们。但是,正如你可能猜到的那样,一种特定的声明已经准备好了,当然,那就是先前被抛弃的Holding Register形式。那么让我们来看看这在实践中是如何运作的。假定我们用户的平行链2000向Statemint发送一条消息,其中它从其主权账户中提取0.01 DOT以支付费用,并通知它有100单位的原生代币被转移到Statemint的主权账户中。如下图所示:假定0.01 DOT是足够的费用,并且Statemint支撑平行链2000的外地资产的链上放款(以及使用平行链2000作为它的贮藏),那么这应当可以一般任务。但是,或许Statemint尚未成立以识别平行链2000的原生资产。在这种情况下,DepositAsset将不晓得如何处理资产并因而引发错误。在执行将向平行链2000通知此缺陷的附录之后,我们将剩下100个平行链2000的外地资产,以及可能在Holding Registe中的一些DOT。假定费用仅为0.005 DOT,盈余0.005 DOT。然后,Statemint的XCM仪表盘会记载这些新的可索赔资产的事情,例如:一条消息将被发送回平行链2000,如下所示:平行链2000将在稍后的某个阶段(或许一旦它肯定Statemint能够接受其外地资产的放款),能够通过一种相当简单的方法收回这100个单位:在这种情况下,ticket参数没有提供辅佐定位索赔的特地信息。这一般适用于资产圈套索赔,固然在其他类型的索赔中可能需要使用。结论希冀这些内容有助于你更多地了解XCM的底层虚拟机,以及它如何辅佐您管理和从不测情况中恢复。本系列的下一篇文章将引见XCM的未来方向以及如何对格式提出改良建议,并深入议论Substrate的XCM Rust完成以及如何使用它来提供一个链能够随意地注释XCM。


              

抱歉,评论功能暂时关闭!

微信号已复制,请打开微信添加咨询详情!