CPU告急,EOS网络拥堵该如何解决?



  • EOS CPU告急,主网再次拥堵

    11月1日,ENU社区的创始人AP在EOS上发行了代币EIDOS(ENU Is Dead,Oh Shit),并再一次通过和ENU相同的代币分发方式对EOS社区进行空投。

    根据EIDOS分发规则,EOS持有者可以发送任意金额到EIDOS的智能合约账户,智能合约会返回等量的EOS和账户池总量的0.01%的EIDOS。

    这意味着,越早期参与的用户能够获得的EIDOS就越多。大量EOS用户涌入到了这场空投活动中,其火爆程度一点不输于当时的ENU。

    然而,就在EOS用户争先想要效仿ENU的暴富神话时,号称百万TPS的EOS却率先崩溃,EOS社区内这场大规模空投活动直接导致了EOS全网拥堵。
    11031.png
    截止到目前为止,EOS的CPU资源价格已提高了将近1000倍,转账一次需要抵押将近7000个EOS。同时主网CPU、NET等资源也一路暴涨,根据EOSpark数据光CPU这一项就上涨了109533.33%。这意味着,超过90%的EOS用户根本无法使用转账功能。

    EOS的资源模型的利弊

    这些问题是出于EOS的资源模型设置,在EOS中用户交易免费,但是必须要抵押足够的资源才能交易。

    EOS将资源分为三类:RAM、CPU、NET,用户可以抵押EOS来换取资源的使用权。

    RAM即内存,用来记录账户信息,包括账户余额、公钥、质押、投票、智能合约等。通常需要3KB-8KB的容量来存储个人EOS账户信息。RAM是可以随时买卖的,每笔收取0.5%的手续费,同时价格也是随RAM的稀缺程度时刻变动的。

    CPU/NET是质押类型的资源。当EOS账户进行转账、投票等操作时,会消耗主网的算力和带宽,此时需要质押一部分EOS来换取CPU/NET,每天使用的算力和带宽会在24小时后重置。质押的EOS是可以随时赎回的,但是会存在72小时的冻结期。

    这种解决方案不同于以太坊等直接收取GAS燃料费。EOS的方式使得交易费在资源充足的情况下,可以免费交易。这大大方便了开发者和使用者。但是因为节点的物理机器的计算能力和存储能力都是有限的,所以整个网络中用户能使用的资源也是有限的。

    这次EIDOS代币空投事件,随着抵押EOS新用户数量的不断增加,价格也不断上涨,老用户原先拥有CPU的比例也会随之缩水,导致用户资源不足,无法交易。同时因为自由市场的缘故,会导致大量用户主动大量购买CPU,造成恶性循环。

    EOSC资源模型的解决方案

    EOSC主网是EOS原力团队在2018年6月基于优化后的EOSIO代码启动的主网,是EOSIO生态的一部分。

    在EOS上线之初,EOS原力团队就曾经指出EOS资源抵押模型的弊端,恶意攻击者只需要抵押数万EOS就能低成本地让EOS全网陷入瘫痪。EOS原力为了使得所有用户都能使用到资源来进行交易,并解决主网运行中产生的一系列问题,对EOS进行了修改,建立了一套新的资源模型, 在保证资源分配公平合理的情况下,尽量减少对于资源的滥用,让真正需要资源的用户可以使用EOSC网络提供的资源。

    和EOS相比,主要有两点不同:

    1) 基于手续费分配的交易方式

    在EOSC中,我们需要用户为其所触发的每一个action支付手续费,这一方式类似与以太坊CPU资源和NET资源是基于手续费分配。每一笔手续费会为其action提供一个CPU和NET的资源使用上限, 对于系统原生的action如转账、创建用户、更新权限等action,可以采用固定手续费和限制的方式便于用户使用,在默认情况下,每次交易支付0.01 EOSC,这样又激励了开发者优化合约代码逻辑,提高资源使用率,又为用户带来了非常流畅的使用体验

    执行过程:

    cleost transfer eosforce test "5000.0000 EOS" "fo test"

    executed transaction: ed62211eda722230472d416a8e3c92ab3f950fe951bcd357f9fb217792dac936 152 bytes 213 us

    eosio <= eosio::onfee {"actor":"eosforce","fee":"0.0100 EOS","bpname":"biosbpb"}

    eosio <= eosio::transfer {"from":"eosforce","to":"test","quantity":"5000.0000 EOS","memo":"fo test"}

    eosforce <= eosio::transfer {"from":"eosforce","to":"test","quantity":"5000.0000 EOS","memo":"fo test"}

    test <= eosio::transfer {"from":"eosforce","to":"test","quantity":"5000.0000 EOS","memo":"fo test"}

    我们用eosforce账户给test账户转账了5000 EOSC,这个交易中只运行了 eosio::transfer action, 所以对于这个action执行了对应的eosio::onfeeaction来向eosforce账户收取了 0.01 EOSC作为交易的手续费。

    注意 eosio::transfer action会触发eosforce <= eosio::transfer和test <= eosio::transfer两个通知,但是这里两个账户都没用相应通知,所以这里只执行了一个action。

    Eosforce会为transaction中的所有action分别计算手续费,这里的action也包括inline action,
    如下面,这里testc是合约账户,当接受到转账时,会向另外两个账户testa和testb转账,这里构建一个transaction,向testc账户转账:

    cleost transfer eosforce testc "5.0000 EOS" "fo test"
    executed transaction: 6339c73f167602607c8ee1a89a73e7f0171f375b39b361eb47047f0e4a48c69d 152 bytes 646 us

    eosio <= eosio::onfee {"actor":"eosforce","fee":"0.0100 EOS","bpname":"biosbpm"}

    eosio <= eosio::transfer {"from":"eosforce","to":"testc","quantity":"5.0000 EOS","memo":"fo test"}

    eosforce <= eosio::transfer {"from":"eosforce","to":"testc","quantity":"5.0000 EOS","memo":"fo test"}

    testc <= eosio::transfer {"from":"eosforce","to":"testc","quantity":"5.0000 EOS","memo":"fo test"}

    apply testc eosio transfer

    eosio <= eosio::onfee {"actor":"eosforce","fee":"0.0100 EOS","bpname":"biosbpm"}

    eosio <= eosio::transfer {"from":"testc","to":"testa","quantity":"5.0000 EOS","memo":"1;testa"}

    testc <= eosio::transfer {"from":"testc","to":"testa","quantity":"5.0000 EOS","memo":"1;testa"}

    apply testc eosio transfer

    testa <= eosio::transfer {"from":"testc","to":"testa","quantity":"5.0000 EOS","memo":"1;testa"}

    eosio <= eosio::onfee {"actor":"eosforce","fee":"0.0100 EOS","bpname":"biosbpm"}

    eosio <= eosio::transfer {"from":"testc","to":"testb","quantity":"5.0000 EOS","memo":"1;testa"}

    testc <= eosio::transfer {"from":"testc","to":"testb","quantity":"5.0000 EOS","memo":"1;testa"}

    apply testc eosio transfer

    testb <= eosio::transfer {"from":"testc","to":"testb","quantity":"5.0000 EOS","memo":"1;testa"}

    warning: transaction executed locally, but may not be confirmed by the network yet ]

    这个过程中,首先是eosforce向testc转账需要0.01 EOSC手续费,之后testc的合约触发了两个inline_action,分别是向testa和testb转账,这里由收取两次0.01 EOSC手续费,所以整个合约会收取0.03 EOSC手续费。既避免了宝贵有限的链上资源被无节制消耗,又使得每笔资源都相对独立不会影响到其他用户的使用体验和智能合约的正常运行,不会遭受“粉尘攻击”。

    2)投票分红分配RAM资源

    与CPU和NET不同,RAM采用租赁方式,以账户为单位根据其所缴纳租金来设置账户可以使用的RAM的上限,这里租金按照时间收取,为了方便用户操作,现阶段我们为每个账户设置了8kb的免租金额度,这样对于绝大多数普通用户是不需要关心RAM的,通常,开发者需要为其DApp所使用的RAM支付租金,包括了合约占据的RAM和执行中产生的RAM数据。

    目前EOS原力实现了通过投票分红来支付租金的功能,在EOSC中用户投票可以获得分红,这形成了一个token流,而RAM租金也是按照时间和租赁的多少来计费,通过分红支付租金,一方面方便用户操作,不需用户经常补交租金和缴纳押金,另一方面可以提高投票率,促进链生态健康发展。

    这个过程是这样的:
    11032.png
    这种类似租云主机的方式以方式分配RAM资源, 用户可以通过使用投票分红来支付租赁RAM资源的费用, 这样即不需要用户担忧租金缴纳问题, 也杜绝了租金欠费的问题. 通过“以租代售”的方式, EOSC可以有效避免针对RAM资源的投机行为, 使得DAPP的发展不必受到RAM价格的干扰, 有效促进DAPP生态建设.

    3) 结语

    这次事件我们可以看出,在EOS整个主网,EOS目前的状态远没有达到TPS交易上限,EOS的资源抵押模型导致EOS无法真正发挥出其出色的性能。这也通过事件证实了EOS的高TPS在区块链中的优势和应用。

    BM在白皮书中表露资源模型的初心是---“降低开发者成本,让用户交易免费”。目前的资源模型还需要进一步的调整和修改。

    EOS目前暴露出的问题在于其CPU资源模型, CPU实际上是一种时效性很强的资源, 在达到整个主网实际性能上限前所有限制用户的加成都是浪费资源, 同时EOS主网不应过分放任和迁就超级节点, 应该鼓励和敦促超级节点更新为良好计算设备, 在此同时开发工具和插件以减少同步节点对应的资源消耗, 所以可以通过以下思路改进:

    增加一个指标衡量性能瓶颈,这个值应该和历史最高tps相关,并且设置一定的基于时间的增速来适应计算技术的发展, EOS主网已经奖励EOS给BP作为激励, BP不应提供过于落后的计算设备。
    增加一个指标以衡量当前实际性能压力,这个指标应该和最近一段时间内的实际cpu消耗和用户抵押cpu总量正相关,链上可以动态调节这两者影响的比值, 这样兼顾性能实际消耗与未来消耗预期。
    增加一个容量窗口加权指标,这个指标同当前性能压力成反比,和历史性能指标成正比,并定义一条以当前性能压力为参数的性能影响梯度曲线作为这个指标的加权值, 用这个指标作为用户cpu资源上限的加权值。
    规划容量窗口指标的刷新机制, 这个机制应该间隔较短以减少用户拥堵预期。

    当前EOSC,允许通过固定手续费和限制的方式来解决此问题。对于CPU和NET资源, 用户可以基于分红票龄支付手续费来达到类似EOSIO抵押获取CPU和NET资源的效果, 对于RAM, 用户可以通过抵押投票互换的形式来达到EOSIO基于市场购买的效果, 这样DAPP开发者也可以快速从其他EOSIO链切入EOSC, 并平滑的转向EOSC的资源模式。同时EOSC去中心化预算系统也近期上线,系统通胀发行的30%进入预算系统。在接下来会随着EOS一起共同发展和繁荣整个 dApp生态。


Log in to reply