热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

平行链上线技术系列二Substrate交易费率和Benchmark

Substrate Transaction fees and Benchmark交易费用存在的意义我们需要为我们的区块链设计手续费,是为了激励参与方更加有效的协作,调节资源的利用率,毕竟天下没有免费的


Substrate Transaction fees 

and Benchmark


交易费用存在的意义


我们需要为我们的区块链设计手续费,是为了激励参与方更加有效的协作,调节资源的利用率,毕竟天下没有免费的午餐。


Substrate 的 Fees 如何计算


使用以下参数计算交易的最终费用:

  • base fee:这是用户为交易支付的最低金额。它在运行时被声明为base weight,在runtime下配置

  • WeightToFee即可。

  • weight fee:与交易消耗的执行时间(输入输出和计算)成比例的费用。

  • length fee:与交易的编码长度成比例的费用。

  • tip:增加事务优先级的可选提示,使其有更高的机会被包含在事务队列中。

  • base_fee、weight_fee 和 length_fee 构成inclusion fee(包含费用)。inclusion fee(包含费用)是交易被包含在一个区块中必须可用的最低费用。


使用  transaction 

payment pallet


pallet-transaction-payment提供了计算 inclusion fee的基本逻辑。

这个pallet提供以下配置项:

  • Config::WeightToFee 将weight转换为基于货币类型的可扣除费用

  • Config::FeeMultiplierUpdate通过定义一个乘数来更新下一个块的费用,基于上一个块结束时链的最终状态。(动态交易费率的配置项)

  • Config::OnChargeTransaction管理transaction fee的取款、退款和存款。


ps: 交易费用在交易执行之前被提取。事务执行后,可以调整事务权重以反映事务使用的实际资源。如果交易使用的资源少于预期,则更正交易费用并存入调整后的交易费用。


交易费用的公式

inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee];

final_fee = inclusion_fee + tip;


细化之后的公式 ->

在这个公式中,targeted_fee_adjustment是一个乘数,可以根据网络的拥塞情况调整最终费用。

  • base_fee其实就是ExtrinsicBaseWeight的大小转换为Balance的值

  • length_fee是交易体存储的费用。

  • weight_fee通过两个参数计算:

   a.在ExtrinsicBaseWeight运行时声明并适用于所有外部变量的 。(base fee)

   b.#[pallet::weight]解释外部复杂性的注释。


要将权重转换为货币,运行时必须定义一个WeightToFee实现转换函数的结构体Convert.


请注意,在调用外部发件人之前,会向外部发件人收取包含费用。即使交易在执行时失败,费用也会从发件人的余额中扣除。


基础费用(base_fee)


是用户为交易支付的最低费用。它在Runtime被声明为base weight,其实就是ExtrinsicBaseWeight的大小转换为Balance的值。所以需要设计Weight转换为Balance的公式 --  WeightToFee,WeightToFee在pallet-transaction-payment处进行配置即可。


关于ExtrinsicBaseWeight的配置

通过runtime下frame_system::Config的BlockWeights 的base_extrinsic进行配置。

关于WeightToFee:

WeightToFee 可以理解为 一单位Weight与一单位Balance之间的映射转换。


Code 实现

在代码实现那块主要是对一个 pub struct LinearWeightToFee(sp_std::marker::PhantomData); 添加WeightToFeePolynomial 宏。


只需要实现这个宏里的 polynomial() 方法即可


polynomial()其实是在定义weight转换为balance的多项式。

关于 WeightToFeeCoefficient 的配置细节

这个返回的是一个多项式公式

其中 negative值 是控制整体多项式是加上该多项式还是减去该多项式

negative的对应关系:

true → -

flase → +

多项式的公式如下

例如:

如果我们想实现一个1:1的WeightToFee的转换,那这里的配置应该是:

对应的多项式为:

小总结:

WeightToFee只是Weight转换成Balance的映射转换,只需要在pallet_transaction_payment指定WeightToFee即可。


因为交易费中涉及到weight的内容不止base fee,还有weight fee,这两个都是把pallet_transaction_payment指定的WeightToFee作为转换公式。


base fee公式:


字节费用(length_fee)


length fee主要计算的是交易体大小的费用。


对于length fee的计算公式:

Length_Fee = 交易体大小 * 每字节所需费用

每字节的费用可以在runtime下pallet_transaction_payment的

TransactionByteFee做定制。

TransactionByteFee  =>  指定每个字节值多少Balance。

其次就是交易体的大小,但是要了解交易体的大小,首先需要了解交易体的内容构造。


关于交易体的构造:

Substrate 入门 - 交易体 -(六)


      在Substrate中的交易不再称为Transaction,而是称为了Extrinsic,中文翻译就是“外部的;外表的;外源性”,意味着被称为Extrinsic的概念,对于区块链而言是外部的输入。这种定义脱离了本身“交易”的范畴(更像是转账的概念),而是在链的状态的角度下,认为交易及类似概念是一种改变状态的外部输入(意味着不止转账,只要是外部的操作都是,pallet func)。


一个“外部输入”至少会具备以下两个条件:

  • 发送者的证明

  • 外部输入的行为


其中第一点是显然的,只要基于公私钥体系,就一定需要发送者对这个发送的内容进行签名,在链上通过这个签名验证合法性,解析出发送者的公钥识别身份。等价于互联网中客户端持有的token这类的。而第二点就是这个“输入”是到链上干嘛的,其相当于是用户发送到链上的指令行为


关于链下如何构造这个signature,

插曲:链下一个交易体的构成:


交易bytes内容的构造:

pallet-func index + 发起人的Account(公钥)+ signature(signed, signature, extra) + call

pallet-func index是通过pallet name 和 function name在metadata里查询得到到index

交易执行之后可以在此处


explorer下观察到signature的信息:

call里的内容主要由call index和参数构造而成。

至此我们获悉了交易体的byte信息

所以对于上述的例子,相对应的字节费用为

其实在这里可以观察到由于交易体的设计,可以实现在发送之前就可以计算出交易的大小从而推导出交易的手续费。

还有其他的玩法:

  • 交易版本与链上版本检查

  • 交易存活性检查

  • 特殊交易的额外信息检查

  • 例如如果一个交易是转账transfer,可以直接检查发送者的余额是否足够,不用到区块执行阶段才判定。

权重费用(weight_fee)


在有限的区块生成时间和链上状态的限制下,权重被用来定义交易产生的计算复杂度即所消耗的计算资源,以及占据的链上状态。system模块定义了区块的总权重(BlockWeights)。


#[pallet::weight(200_000, xx, xx, xx)]


为了保证在网络繁忙的情况下,依然能够实现对区块链应用有效合理的管理,Substrate引入了三种不同级别的交易类型,既 Normal、Operational 和 Mandatory 类型。


Normal类型的交易是由网络中的普通用户提交,

Operational类型的交易是由网络中的管理员或者管理委员会共同触发。


Mandatory类型的交易表示网络中区块交易所必须的交易信息,通常是内在的交易,由验证人触发。


区块资源如长度和总权重按照一定比例在这三种类型的交易中进行分配,这一比例称为可用区块比(AvailableBlockRatio)。Kusama网络的设置为:

10^12 weight = 1s

1000weight = 1ns

  • 区块的总权重:2,000,000,000,000 weight(2秒)

  • 可用区块比:75%,即Normal交易最多只占用75%的区块资源,Operational类型的交易则可以占用100%的区块资源,新的交易如果导致对应资源使用率超过阈值后,会被拒绝。对于Mandatory类型的交易,即使在区块已经满了的情况下,依然可以把交易打包进区块内。


1、默认weight注释

Substrate 中的所有可调度函数都必须指定权重。你可以使用注释的方式


#[pallet::weight(xxx_xxx)] ,这个规范允许你组合包括 数据库读/写,权重的固定值 以及 基于banchmark的固定值。下面是一个基本的demo

ps: ExtrinsicBaseWeight 会自动添加到声明的权重中,以考虑将空的外部数据简单地包含到块中的成本。


对数据库访问进行参数化

为了使权重注释独立于部署的数据库后端,它们被定义为一个常量,然后在表示可调度执行的数据库访问时在‘注释’中使用:

2、自定义weight

可以创建自定义重量计算类型,而不是使用上述默认重量注释。此类型必须实现以下特征:

  • WeighData: 确定发货重量。

  • ClassifyDispatch:确定调度的类。

  • PaysFee:确定可调度的发件人是否支付费用。


最后,weight fee的公式:


动态调节费率

(targeted_fee_adjustment)


设置  FeeMultiplierUpdate 参数即可


细节深入—— Relay-chain transaction fees and per-block transaction limits


Token Economics - Research at W3F


区块链上的交易需求通常非常不规则。一方面,在一天内的小时或一个月内的天数范围内存在活动高峰。另一方面,有长期趋势的交易量增长趋势。我们需要一种机制,在考虑这些因素的情况下,随着时间的推移自动更新交易费用。


根据供求规律,提高费用就可以减少需求,降低费用就可以促进需求。


为了应对活动高峰,我们面临着在快速提高交易费用或可能有很长的交易包含时间之间进行权衡——两者都是不良影响。我们提出了两种机制。第一种快速调节机制(Fast adjusting mechanism),可以非常迅速地调整价格,与活动的高峰和低谷同步。第二种慢速调整机制(Slow adjusting mechanism),是以长期趋势的速度进行缓慢调整,并使用小费为用户提供在高峰时段控制等待时间的可能性。parity官方建议使用带有tips的慢速调整机制。


关于动态调整机制的设置,也是在pallet_transaction_payment下进行配置。


小费(tip)


小费不是必须的的,具体数量是由交易发送者决定的,并且完全由区块生产着获得;


而交易费用的其他组成部分会根据一定的比例进行分配,国库80%,区块生产者20%。


题外话:最后的手续费去哪里了


至此关于交易手续费的内容,就全部介绍完毕,我们也进一步了理解了各个参数的含义,这个时候我们再回头看细化之后的公式,就能理解底层计算的计算逻辑了。


关于手续费最终计算的代码:https://github.com/paritytech/substrate/blob/polkadot-v0.9.18/frame/transaction-payment/src/lib.rs#L505-L537


关于 Benchmark


Substrate Benchmarking Documentation


benchmark主要是用于调整weight的内容,字节费用通过配置pallet_transaction_payment的runtime即可解决。


在 Substrate 中,10^12 个weight单位 = 1 秒,或 1,000 个weight单位 = 1 纳秒。


为什么需要使用benchmark


拒绝服务 (DoS) 是分布式系统(包括区块链网络)的常见攻击媒介。这种攻击的一个简单示例是用户重复执行涉及密集计算的外部函数。为了防止用户向网络发送垃圾信息,我们向用户收取发送cal的费用。调用成本应反映系统产生的计算和存储成本,调用越复杂,费用越高。但是,我们仍然希望鼓励用户使用我们的区块链系统,所以我们也希望这个估算成本相对准确,这样我们就不会向用户收取不必要的费用。


基准测试允许开发人员向最终用户收取适当的交易费用,以更准确地表示系统上的外部成本。设置合适的权重函数,准确反映底层计算和存储,也是 Substrate 中重要的安全保障。


简单的理解:weight可以手动设置,但是每台机器的性能可能不一致,可以使用benchmark做一个测试然后测算出指定机器下 weight的大致范围。


确定机器配置


在进行benchmark之前,我们需要先确定机器的配置信息。


Benchmark的可用选项


进行Benchmark测试


在pallet下创建benchmarking.rs文件

编写完benchmark之后 需要在生产机器下去进行benhmark测试。

关于benchmark的一些配置项:

你可以指定weight的模版生成定制之后的weight文件


模版文件

./.maintain/frame-weight-template.hbs内容:

根据模版文件生成指定的weight文件

测试完成之后,关于weights的值也就估算成功了,在pallet里引入weight即可


Other link

https://github.com/paritytech/subport/issues/149

中如何计算工龄在Substrate中如何计算交易权重姒煜的博客-CSDN博客

Gavin:关于 Weight 你必须了解的要点哔哩哔哩bilibili

Token Economics - Research at W3F

https://github.com/paritytech/substrate/pull/3157

Substrate 入门 - 交易体 -(六)

play-substrate/lib.rs at master · kaichaosun/play-substrate

Substrate 区块链应用的交易费用设计

[教程]波卡Substrate pallet开发的权重计算与基准测试

在Substrate中如何计算交易权重

weight and fees

post dispatch weight correction

calculate fees




通过 DAO,研究组织和媒体可以打破地域的限制,以社区的方式资助和生产内容。DAOrayaki将会通过DAO的形式,构建一个满足人们需求,一个民主治理和所有人都可以利用的公共媒体系统,从而实现真正意义上的去中心化。欢迎通过以下方式提交星际移民、量子计算、DAO的相关研究,瓜分10000USDC赏金池!了解去中心化自治组织(DAO),探讨最新治理话题,关注DAO的发展趋势,欢迎加入DAOrayaki社区!


官方网站:daorayaki.org
Discord server: https://discord.gg/wNUPmsGsa4
Medium: https://medium.com/@daorayaki
Email: daorayaki@dorafactory.org
微信助手:DAOrayaki-Media
Twitter: @daorayaki_
小宇宙:DAOrayaki


详情请参考:
Dora Factory支持去中心化DAO研究组织DAOrayaki
对DAOrayaki第一阶段的回顾--去中心化媒体的先驱
DAOrayaki |DAOrayaki 开启去中心化治理2.0时代
DAOrayaki |风险投资的范式转移:无限主义基金和无限游戏
DAOrayaki |DAOrayaki dGov 模型:基于Futarchy的正和游戏

更多关于DAO的文章,关注Dorafactory,查看往期文章。

推荐阅读
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 去掉空格的方法——Python工程师招聘标准与实践
    本文介绍了去掉空格的方法,并结合2019独角兽企业招聘Python工程师的标准与实践进行讨论。同时提供了一个转载链接,链接内容为更多相关信息。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
author-avatar
oko123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有