批量发送交易,部分交易不打包

问题描述:同一个用户,批量发送了500笔上链交易,部分交易hash查getTransactionReceipt一直为null,期间链一直正常出块

交易描述:同一个合约的同一个方法,参数不同,valid_until_block=88

请教这个问题发生可能的原因有哪些?

想先确认一下:

  • 交易 quota 设置了多少?
  • 生成链的配置是怎么样的?

你可以先查一下 getTransactionReceipt 那个节点的 cita-forever.log 是否存在微服务重启的记录。或者用工具 cita-op-help 把日志发出来给我们看看。

quota设置的220000000
整个链只有一个共识节点
cita-forever.log没有微服务重启的记录

重新发送了300笔是都成功了。之前500笔没有成功的应该是超过了88块就不打包了。

没有特别设置过 BQL 吧?它的默认值是 1073741824,

你将交易 quota 设置为 220000000 , 意味着一个块只能放下

1073741824 / 220000000 = 4 

个交易。而 valid_until_block = 88 则意味着:

4 * 88 = 352

个交易之后的交易将不能上链,获得不了 Receipt

解决的办法是:

  • 减少交易 quota; 或
  • 增加 BQL; 或
  • 增大 valid_until_block,注意 valid_until_block 最大只能设 100; 所以不太建议这个方法。

另外,我在上次的分享中,还专门讲到了这个问题:

欢迎观看回放!:blush:

1赞

感谢。
quota 设置为 220000000,如果交易花费不掉会返回quota吗?每个块计算包含的交易笔数是按照初始化设置的quota而不是真实花费的么?

是按照交易设的 quota 来计算的。
CITA 采用的是先共识后执行的方式,所以块进行打包共识的时候,并不知道一个交易的实际 quota 消耗是多少。

增加BQL会影响出块时间间隔吧
有没有类似 eth_estimateGas动态计算所需quota的方法?

没有哦,你可以用 hash 查一下当前已经上链的交易,看看实际的 gas_used 是多少,再填一个相对比较合理的值就行了。

  • quota -> 交易的配额。
    看文档中有写有配套工具,合约是solidity写的

1、接口比较多,看历史gasused有点。。。
2、部分方法随着业务进行,可能消耗的quota会增加,历史gasused可能不好参考

CITA 没有这个工具,文档写得有点问题。 我们会马上把文档改掉。

你们同一接口的功能逻辑还会随着业务进行,消耗的 quota 会不断增长吗?
问一下,您现在的一个交易实际的 quota 消耗是多少?

会有可能吧,比如交易逻辑因为循环数增加消耗更多的quota。
另请问,如果一个交易因为超过了valid_until_block 而没有被打包,能根据这个交易hash查询某种方法判断出来吗?
这种交易相当于是被共识节点抛弃了,会被扔到哪里,还有没有办法能获取到?

查回执可以看到 “Out of Quota” 的错误。
这个交易还是在链上,只不过没有执行成功而矣。

Out of Quota是在quota设置不够的时候出现的错误。
我只的是在超过valid_until_block不被打包的交易,查询回执是null

这两者是不一样的:

  • 如果是 valid_until_block 到了而没有被打包,这个交易会被抛弃,也不会放到链上,回执就是 null。
  • 如果是 Out of Quota 的错误, 这个交易是被打包并执行过的,只是执行错误了。回执就是一个 Error。

我意思是有没有办法判断这个交易是因为valid_until_block 到了而没有被打包。因为查询回执是null只能说明交易没有被打包(也有可能是正常的还没来得及打包)。如果能判断就可以在业务上控制重新发一次。

其实 valid_until_block 到了而查到的回执是 null ,就表明这个交易没有被处理过,以及后面也不会被处理。
我理解有这个结果,你就可以控制是否重新发送,不是吗?

我理解你的意思是在签名交易的时候要记录一下这个valid_until_block,这样确实可行。

我意思是有没有办法通过某个rpc接口区分1、没来得及被打包的交易 和 2、valid_until_block超出再也不会被打包的交易
这两种情况 getTransactionReceipt返回值一样。

暂时没有。