BCSkill (Block chain skill )
区块链中文技术社区

只讨论区块链底层技术
遵守一切相关法律政策!

cleos system claimrewards Error 3050003 “quantity exceeds available supply”

在测试网中,获取出块奖励时,报错

surou@bcskillsurou:~$ cleos -u http://127.0.0.1:8000 system claimrewards bcskillsurou -p bcskillsurou
Error 3050003: eosio_assert_message assertion failure
Error Details:
assertion failure with message: quantity exceeds available supply
pending console output:

查询supply

surou@bcskillsurou:~$ cleos -u http://127.0.0.1:8000 get currency stats eosio.token EOS
{
  "EOS": {
    "supply": "10000000000.0000 EOS",
    "max_supply": "10000000000.0000 EOS",
    "issuer": "eosio"
  }
}

发现supply已经不小于max_supply。
由于bp每次claimrewards时,根据距离上次claim的时间差先增发,然后再从奖池里面拿。所以每次claimrewards时,supply都会增加相应的值,但必须小于max_supply。
继续跟进

创建代币
cleos -u http://127.0.0.1:8000 push action eosio.token create '["eosio","10000000000.0000 EOS",0,0,0]' -p eosio.token
发布代币
cleos -u http://127.0.0.1:8000 push action eosio.token issue '["eosio","10000000000.0000 EOS","issue"]' -p eosio.token

发现是当时启动测试网时,issue发行了最大的值,一般应小余最大值10倍,及创建100亿代币的最大值,只发行10亿,之间的差额用于增发。
参考:https://github.com/EOSIO/eos/issues/4325

"Dapp"你们走的太快了,请等等你们的"EOS"

80天80亿流水, EOS DApp生态大爆发,CPU价格水涨船高,这是一个很正常的市场行为,需求大了,价格自然上涨。但是如果你仔细看看数据就会发现,目前EOS TPS平均只有50,理论上CPU肯定是空闲的。既然是空闲的,CPU没有涨价的理由啊。所以这里就存在一个问题,要么是CPU价格虚高,要么就是目前系统配置下,EOS TPS极限就是50左右。


为了一探究竟,就必须先分析分析CPU价格的计算机制。

CPU资源价格计算机制

CPU的价格是指1个EOS可以使用多长时间的CPU,所以CPU价格自然受两个指标影响:一个是CPU资源总量,一个是CPU需求量。

由于EOS投票必须抵押,因而系统中抵押的EOS有很多只是用来投票而不是用来使用CPU的,自然没法判断当前CPU的真实需求量,自然没法计算出CPU的价格。于是EOS提出了虚拟CPU资源的概念,CPU的价格=虚拟CPU资源总量/系统总的EOS抵押量。这个虚拟CPU资源总量是动态调整的,是根据过去1分钟CPU真实使用量动态调整的,当CPU真实使用量大于某个阈值(目前是CPU总量的20%)时,认为CPU处于繁忙了,会调低虚拟CPU总量即提高CPU价格以降低需求量,如果CPU使用量还是没下来(交易量还是没减少),虚拟CPU总量会继续降低,直到很多用户因为CPU不够或超支没法发起交易,然后CPU使用量自然就下降了。反之CPU闲时,CPU价格会降低,用户能够发起的交易增多,自然交易量就大了,CPU使用量就会上升。因此,这个机制还是非常市场化和实时的。这个虚拟CPU量最大为真实CPU量的1000倍,这其实间接认为,抵押的EOS中用来兑换为CPU的那部分占比最少为1/1000。这个虚拟CPU总量没有下限,下限是根据CPU使用量来调整的。下限是直到CPU的使用量低于真实CPU总量的20%才开始不降低或回升。

由于这个CPU价格实时动态调整机制,在一个活跃的市场内,CPU的使用量应该会在阈值(20%)这个量上下波动。事实上数据显示也如此

同时CPU价格应该也有忙闲之分

从上可以看出,凌晨2点开始变闲,凌晨4点到6点最闲,从一定角度可以看出,EOS中国及东南亚国家玩家多。

更长时间的CPU价格图也表明几乎每天都是4点到6点最闲。


上面分析提到CPU的最大使用量就在阈值附近。所以在CPU真实总量确定的情况下,这个阈值是EOS最大TPS的唯一影响因素。那这个阈值又是如何确定的呢?这个阈值就是前一段时间广泛报道的TARGET_BLOCK_CPU_USAGE_PCT。

10月18号EOS通过决议将TARGET_BLOCK_CPU_USAGE_PCT

的值从10%提升到20%,所以TPS在10.18号后得到提升,还是继续看数据。

从上面可以看出,10.18后的2天,社区立马做出了恰当的反应,TPS在短短2天内快速从20左右提升到50的极限TPS并一直保持。
再看看看这个变动后,CPU的真实使用量变化

从上可以看出CPU的使用量也从10%缓慢上升到了20%极限附近。

TPS极限

EOS通过区块CPU总量来调节TPS的极限值。
区块CPU总量=MAX_BLOCK_CPU_USAGETARGET_BLOCK_CPU_USAGE_PCT=2000.2
0.5s产生一个区块,也就是1s中可用2000.22=80ms的CPU

我们以EOS转账为例来说明一个transaction的CPU消耗,目前一个转账交易需要消耗1ms CPU,所以如果EOS中都是EOS转账交易,那么目前EOS TPS理论最高值是80, 但是由于目前很多交易是game类的Dapp,一个交易可能有很多inline action,所以一个交易的耗时是EOS转账交易的2倍左右,从而TPS下降到50左右,和上面的数据分析结果吻合。

TPS如何提升

1)提高TARGET_BLOCK_CPU_USAGE_PCT,这个参数是一个配置,自然可以通过BP提议修改以提高TPS上限,并降低目前CPU价格
2)TARGET_BLOCK_CPU_USAGE_PCT的提升是有限的,最多提升到100%,也就是目前TPS的5倍,所以TPS上线最多达到50*5=250
3) 目前MAX_BLOCK_CPU_USAGE设置为200ms, 1s两个区块,所以1s限定使用400ms, 只占了总时间的40%,这个参数不配置为100%是因为BP节点的CPU除了处理交易,还需要处理网络请求等其他业务,比如交易接收广播,系统软件自身CPU损耗。但是这个40%比例偏低,有提升的可能。
4)EOS系统优化,目前EOS是单线程,BP的超级多核(128核)使不上力,如果并行优化加入,应该可以提升不少。

CPU资源生态优化方向

富人的无成本“倒奶行为“

只提升TPS对改善CPU生态是治标不治本的行为。因为TPS一提升,在达到TPS阈值之前,CPU的价格就会很便宜,由于CPU是免费的,自然会有人发起廉价的交易消耗掉掉这个提升的TPS。上面提到的TARGET_BLOCK_CPU_USAGE_PCT从10%到20%将TPS提升1倍,两天就被吃掉就是一个实例。

CPU资源有价格,但是却是免费的,是CPU资源生态乱像的根源。cpu不够的时候,会出现两个极端。穷人没有CPU,富人一大堆,且有一天有效期,很有可能低效使用甚至乱用。

免费从来就不是资源的最佳分配方式,因而我个人觉得适当的收费是CPU资源生态的一个可能方向。

CPU资源适当收费方向(租赁模式)

CPU资源已经设计成免费模式了,直接在代码中更改为收费不太合理,改动量也大。因而从经济学生态角度来实现CPU适当收费是一个相对安全软改动的方向。具体就是大力发展CPU租赁业务,用户大部分交易通过低价但非免费的租赁方式购买CPU资源。

目前CPU租赁生态已经很红火了,几乎所有钱包(TP, Hoo, MeetOne, 麦子钱包)都支持法币租赁CPU,各大超级节点比如EOS42, Laomao也搭建了租赁平台。但是目前的CPU租赁业务没法承载CPU资源适当收费功能,因为目前租赁生态里的可用EOS太少了,会导致CPU租赁价格过高。租赁生态可用EOS太少原因如下:

EOS所有权目前有3类:资源使用权,投票权,糖果权,由于糖果权属于不确定性资产(需要其他人给你空投),这里只考虑资源使用权和投票权。同时,用户在投票前必须先抵押EOS,而CPU资源的“租客"是一个动态积累撮合的过程, 用户投票前,很难立马找到"租客"出租抵押EOS,但为了投票,它只好给自己抵押,哪怕他并不需要使用CPU,所以投票的那些EOS很难流入租赁市场。你可能会说,用户可以先抵押给自己然后投票,等有租客了取消抵押,然后再租给租客。但是要想将已经抵押的EOS重新抵押给其他人,需要先取消抵押,而取消抵押有3天的回收期,租客是等不了的,同时3天的无票期也是用户不能接受的。所以事实上目前EOS这个投票权是一个不太自由的权利,它依赖抵押这一行为。那为啥EOS要这样设计呢?这是因为投票后,你相应的EOS需要冻结,要不你投票后立马转账,计票模块还需要更新投票信息,相当于需要监控转账等其他行为,于是通过先抵押这一统一的操作先冻结相应的EOS。所以,为了发展健康的CPU租赁市场,必须切割投票权和资源使用权(抵押行为)。具体怎么做呢?就是用户不用抵押即可投票,EOS仍需冻结,但是这些投票冻结的EOS可以继续抵押给自己或者抵押给别人(出租),这样分割后,那些投票大户自己就可以开设CPU租赁平台赚钱,或者无心打理的可以交给第三方专业的CPU租赁公司。其实REX就在往这方面尝试,购买REX的EOS可以投票就是一种不抵押投票行为,REX本身又是一个CPU租赁平台,所以投票用户通过购买REX完成了投票和出租EOS两个操作,可见REX从一定角度上是能完善CPU生态的。REX对目前”民营“租赁平台的影响后续我可能会单独写一篇文章,大家可以关注。

完善后的CPU生态可用房市来类比,租售并举,租是一种普世的保障措施。

总结

目前的CPU价格是真实的市场反馈,目前的50TPS是极限TPS,TPS长时间保持满负荷运行,说明需求旺盛。
EOS价格有忙闲之分,凌晨4-6点最闲,CPU紧张的可以试试这个时段。

在TPS极限没有提升之前(TARGET_BLOCK_CPU_USAGE_PCT),Dapp的推广者不要花全部精力在拉交易量上了,因为TPS总量是定的,市场总交易量几乎是固定的了,整个系统是交易存量市场,零和游戏,一个Dapp多了交易,其他Dapp就会少一些交易,大家可以尝试优化优化下智能合约,尽量少耗一些CPU吧。

目前这个状态,用户经常不能操作,新用户的体验肯定是谈不上爽的,所以在引入新用户的时候,适当给与关怀和指引。
EOS社区需要多花点心思在EOS性能优化和TPS上了,REX也请快点发布吧。
”Dapp“你们走的太快了,请等等你们的“EOS"。

附录

EOS进化“臆想"图

时不时被冻结的资产头脑风暴

普通用户可能只会抵押少量EOS,但是CPU价格的波动导致用户CPU不足或者超支,进而用户没法执行任何交易,用自己的EOS给自己抵押CPU的交易也执行不了了,账号处于冷冻状态。这就存在一个问题,我明明有EOS余额的,但是我没法抵押CPU。我的资产已经不由我做主了。针对这种状态,已经有“民间”商业活动解决了,法币租赁CPU,用租赁的CPU解冻,然后就可以用自己的余额抵押更多的CPU。但是本来是可以设计成用自己余额给自己抵押CPU的,为啥要多出这个花钱租赁操作呢?所以在EOS系统层面增加CPU不足时允许用余额抵押CPU这一功能是有必要的。如果系统层面不能做出改动,那民间是可以想办法的。我这里就有一个想法:

当一个账号CPU不够时,肯定是需要第三方来抵押CPU激活的。作者很早以前就做过免费互助抵押,但是目前这CPU价格,免费业务做不下去了,需要太多EOS了,没法及时补充。所以我想到另外一个思路,被救账号(A)先用scatter等工具发起一个离线交易签名(不需要CPU),比如A签署一个A转给B 10 EOS的离线交易T1,并将这个数据发给B。有了这个离线交易T1,B就给A抵押10EOS, A就有了足够的CPU.然后B发起离线交易T1, T1执行后就返回了10EOS给B,这样B的EOS池的容量保持不变,可以继续这个免费业务。这个过程可以这样类比,借方A在银行有1万元钱,取钱需要手续费100元,但是A身无分文,取不出来。A就向B借100元钱,B知道A有1万元钱,但是B担心A借了钱不还,所以B需要A写一个“A欠B100元钱"的借条,有了借条,B就无后顾之忧了,于是借给A100元, A拿着100元就可以取钱了,B凭借借条也可以拿回100元。上面1万元就是A用户的EOS余额,借条就是离线交易签名。当然这个方案有一些小问题,需要大家更加完善,比如同步问题。

CPU计算逻辑源码

转载自区块链斜杠青年

Returning WAST from get_code is no longer supported

问题来自 https://github.com/EOSIO/eos/issues/5640
解决方案:
To clarify: get code still works, but now retrieves wasm instead of wast. To function correctly your cleos version must match the api node’s version because of the changes.
澄清:获取代码仍然有效,但现在检索wasm而不是wast。 要正常运行,由于更改,您的cleos版本必须与api节点的版本匹配。

在没有装cleos的机器无法获取,则在rpc机器添加运行参数code_as_wasm=true

还可以使用
get_raw_code_and_abi,然后把返回里的wasm字段先base64解密 然后再求sha256

1.3.x没有这个get_code_hash,之后版本如果只要code_hash 的话 不要用 get_code 直接用 get_code_hash 这个API。