背景提要:主观计费和交易丢失

EOS网络偶尔会出现交易丢失的现象。

具体来说,EOS 网络上的节点有时无法通过网络将交易传递给当前活跃的区块生产者。导致这类问题出现的原因通常是主观计费。

本文探讨了主观计费和其存在的原因。此外,文章还对EOS网络基金会资助的API+核心工作组发现的关于主观计费问题展开阐述,并提供了解决这类问题的参考指南。在未来,我们将更详细地探讨现有的修复方法,并研究Mandel 3.1版本中的额外功能。

什么是主观计费?

主观计费是EOSIO中的一项功能,它允许节点自主对帐户资源进行本地计费,而无需与网络的其他部分共享计费。主观计费功能自引入以来,使得节点CPU使用率减少了近 90%,但有时也会导致交易持续失败或交易丢失。当在区块链上运行的智能合约代码使用“检查”函数(如 assert() 或 check())来验证时,往往会导致出现主观计费问题。

了解交易的生命周期有助于更好地了解“主观计费”功能。

在EOSIO中,使用节点之间的点对点(P2P)网络连接完成交易。在P2P网络中,节点配置和网络延迟会影响交易在节点间运行的路径。

图1-P2P网络的常规运行

如图1所示,EOSIO交易的生命周期始于用户向API节点提交交易(1.1)。API节点在内部将交易传递给其P2P协议(1.2),后者通过P2P将交易传递给另一个节点,后者又将交易传递给另一个节点,如此反复(1.3),直到交易最终到达生产当前区块的区块生产者(BP)(1.4),之后,活跃的BP将交易纳入区块(1.5)并向账户支付资源。网络中的每个节点独立决定是否将交易传递给其他连接的节点,或者也可能由于内部检查失败或资源过度使用而导致交易失败。

与其他区块链不同,当有效签署的交易因某种原因失败时,EOSIO链不会对所使用的资源计费。 主观计费允许单一节点这样操做。

“主观”是指计费仅适用于在节点运营商的服务器上运行EOSIO应用程序节点的单个实例。 “计费”是指对处理交易所使用的节点资源收取费用。 简而言之,主观计费允许单个节点对其失败的交易计费,并进行本地追踪,而无需将计费包括在生产的区块中。 当交易传递到主观计费的节点时,节点会验证签名并识别发送它的帐户。 如果帐户超过其主观计费限制,则节点将放弃交易。

2019年末,在节点资源过度使用,节点不堪重负的背景下,引入了主观计费。具体来说,节点开始接收大量通过签名验证的交易,但在执行期间未能通过内部验证 ,例如断言失败。这些失败交易使区块生产者 (BP) 和API节点不堪重负,因为验证失败的交易仍使用服务器资源。与此同时,节点因忙于使用资源来处理失败交易,导致许多有效交易从未进入区块。因此,有些区块甚至是空的。

选择主观计费工具,旨在通过减少必须处理的失败交易来减少节点的负载。图2展示了节点选择主观计费功能的资源费用。

图2-“主观计费”下资源使用一览图

“主观计费”功能应用在签名验证后的交易失败上(2.1)。通过少量主观计费,交易通常是成功的。 对于这些成功的新交易,临时的主观计费会被记录在链上,并被客观计费所取代(2.2)。

若账户资源的主观计费过多,交易将会失败(2.3)。对于从未出块的失败交易,节点会收取主观计费,但不会增加链上的费用。每个通过节点路由后的失败交易,则相应会增加这一节点的主观计费(2.4)。

帐户需要拥有足够资源来支付新交易的主观计费(2.5)。 在短时间内,这会增加通过该节点的所有交易所需的账户资源,直到主观计费在24小时内衰减 (2.6)。

根据不同节点的性能影响,一些节点会将交易传递给下一个节点,而另一些节点会因超出帐户允许的资源而放弃交易。

与常规资源计费和PowerUp机制相似,默认的主观计费衰减参数设置为24小时。Mandel3.1中的新功能将允许节点在初始化时,设置其主观计费衰减参数。这个选项将允许调整帐户的主观计费归零所需的时间。

许多区块生产者和一些API节点都使用了“主观计费”功能,这已将节点CPU使用率降低了近90%。

主观计费面临的挑战

虽然主观计费在防止空块和减少节点的负载方面是有效的,但它有副作用,可能导致用户的沮丧和困惑。

对帐户进行主观计费的节点会把计费当成额外的资源费用,并计算在该帐户的所有交易中。

在下一次,该节点收到相同账户的交易指令时,该帐户必须有足够的额外资源来覆盖其此前失败的交易,才能开始新交易。 若该账户没有足够的额外资源,节点将验证签名,放弃执行其剩余交易。

图3-API节点下的主观计费

如图3所示,一些用户在提交交易时反复收到错误信息,尽管区块浏览器显示有足够的资源。发生这种情况的原因是,在用户不知情的情况下,连接到了一个API节点(3.1),该节点对他们的账户应用了主观的计费。提交的交易失败了,但至少当节点返回错误信息时,用户知道出了问题(3.2)。

如图4所示,更坏情况的是会没有任何报错信息。 一些用户成功地将交易(4.1)提交到 API 节点(4.2),但未在区块中看到交易。

这类问题通常发生在中继线路(4.3)到活跃的区块生产者节点(4.4)过程中,且有足够的主观计费资源来阻止通过网络传递交易的情况下。随着计费余额的减少,这些问题可能会持续长达24小时。

如图2 (2.4)所示,不断重新提交失败的交易会不断增加主观计费,也会进一步加剧问题的恶化。

交易丢失工具

主观计费发生在每个节点的本地范围内,且缺乏共享主观计费数据的协议,因此用户很难找出交易丢失的原因。 各个节点运营商可以构建和共享自己的主观计费数据共享工具来进行故障排除,但如果没有全链解决方案,互操作性就会受到限制。

EOS Nation构建了一个用于寻找失败交易的数据共享工具原型,但数据孤岛限制了该工具只能查找自身节点处理的交易。 您可以通过https://eos.api.eosnation.io/transaction_lookup寻找相关交易。广泛共享的数据馈送工具可以使用户和应用程序通过主观计费来了解交易失败的原因,识别漏洞,并诊断其他问题。

Mandel的发布包括对许多这些问题的修复措施,只要区块生产者、节点运营商、钱包和dApp开始使用新功能。但开发和采用需要时间。幸运的是,开发人员和运营商可以将现阶段的缓解措施应用到其工作流程中,直到应用程序和节点正式使用新的Mandel更新版本。

在接下来的几周内,我们将为节点运营商和智能合约开发人员公布开发现状,并重点介绍计划在未来版本的Mandel发布的新功能,包括API+蓝皮书中提出的交易生命周期功能。

我们提供下列内容作为快速参考指南,并提供给操作人员用于测试潜在解决方案的可行性。 此外,我们将会在下一篇文章中更为深入地探讨这些方案。


修复主观计费和丢失交易问题的快速参考指南

每个节点的操作人员可以判别哪些账户不太可能发送太多失败交易,并使用下列方法禁用这类账户的主观计费:
disable-subjective-account-billing = <accountname>

举个简单的例子:节点运营商可能会认为“Greymass Fuel“这一账户具有足够的速率限制或抵御女巫攻击。那么,运营商可以使用以下方法禁用Greymass Fuel的主观计费:
例子:  disable-subjective-account-billing = greymassfuel
‎‎

在nodeos 2.x的现存问题下,节点使用disable_subjective_api_billing 和disable_subjective_p2p_billing作为可选参数时,应确保将两者设置为相同的布尔值,均为true或均为false。而Mandel 3.1版本有望解决这些问题。
‎‎

此外,运营商还可以使用disable-subjective-billing = true 将主观计费完全关闭。

云节点可以使用database-map-mode = heap 把临时文件系统(tmpfs)视为挂载交换分区,以此减少磁盘读取和资源使用。

智能合约应避免assert()和check()函数,因为两者均可能导致交易失败和主观计费。相反,开发人员可以使用return函数来保证所有计费都是客观且在链上的。

API+ 工作组

栏目简介:该系列文章概述了EOSIO的交易生命周期,重点介绍了主观计费功能以及可能导致的交易丢失。 首先,我们将了解有关主观计费的所有细节。 其次,我们将阐述当前智能合约开发人员和节点运营商避免此类问题的最佳实践。 第三,我们会再来阐述Mandel中的缓解此类问题的一些新功能。



关于EOS

EOS网络是区块链3.0时代的典范之作,由EOS VM提供支持。EOS VM是一个低延迟、高性能和可扩展的WebAssembly引擎,能够近乎无感的实现确定性交易执行。EOS网络专为Web 3设计,致力于实现最佳的Web 3用户和开发人员体验。EOS是EOSIO协议的旗舰区块链和金融中心,并通过EOS网络基金会(ENF)作为多链协作和发展公共基础产品的工具,进一步完善基础设施,驱动EOS快速发展。

EOS网络基金会

EOS网络基金会是一个非营利性的组织,旨在倾听社区声音、传达社区意愿并扶持社区优质项目发展,成为EOS社区的信息共享桥梁,并为EOS生态提供资金、技术、运营、未来规划、生态构建等关键基础设施支持,进一步发挥EOS作为世界速度最快的治理型区块链的全部潜力。