之前有朋友在论坛里问到,为什么发了一批交易,而有些交易却没能上链,或者没有按预期时间及时上链。如:
这个问题与 Quota 及 Quota Limit 有很大的关系,那这周就和大家聊聊 CITA 中的 Quota 与 Quota Limit。
CITA 中设计的 Quota 主要是为了处理合约执行的停机问题(关于停机问题后面会专门和大家聊),也就是说向 CITA 系统中发送的每一笔交易都必须设置参数 Quota,以表征这个交易所能消耗的 Quota 上限;交易在系统中执行的每一个步骤都会消耗相应的 Quota 数量, 当Quota 消耗完,而交易没有执行完,系统就会报 “Out of quota” 错误。就好像你在规划了一个项目,并规定了项目的预算,而项目执行的每个步骤都是要花钱的,当钱花完了,而项目没有做完,那就要报 “超预算” 错误 ,项目失败。
CITA 是以时间为顺序按区块的数据格式将交易及其执行状态写入数据库的。为了保证一个区块中的交易能在一个出块时间周期内能顺利执行完 (否则所定就出块时间就会失去意义),设计了一个区块中所有交易的交易消耗的 Quota 数量上限,叫 BlockQuotaLimit ;又由于 CITA 是采用先共识再执行的策略,也就是在共识的时间没有办法知道某个交易的实际 Quota 消耗,所以就变成了:
区块中的所有交易预设 Quota 总和 < BlockQuotaLimit
所以,每个业务链都应该根据自己的实际情况来调整链的 BlockQuotaLimit 、出块时间以及交易 Quota, 来达到 CITA 系统的最佳性能。
如何设置 CITA 的 BlockQuotaLimit ?
参考:
如何设置 CITA 交易的 Quota ?
如果使用 cita-cli 发送交易,其默认的交易 Quota 是 10_000_000
:
cita> rpc sendRawTransaction --help
>> rpc-sendRawTransaction
Send a transaction and return transaction hash
USAGE:
rpc sendRawTransaction [OPTIONS] --code <code> --private-key <private-key>
FLAGS:
-h, --help Prints help information
OPTIONS:
--code <code> Binary content of the transaction
--address <address> The address of the invoking contract, default is empty to create contract
[default: 0x]
--height <height> Current chain height, default query to the chain
--chain-id <chain-id> The chain_id of transaction
--private-key <private-key> The private key of transaction
--quota <quota> Transaction quota costs, default 10_000_000
--value <value> The value to send, default is 0
--version <version> The version of transaction, default is 0
你也可以使用 --quota 来指定一个交易的 quota 值如:
cita> rpc sendRawTransaction --quota 1000000 ...
能不能事先估算一个交易的 Quota ?
可以。现在 CITA 的 develop 分支代码已经合入了这个功能,在下个 CITA 版本,大家应该就可以用上这个特性。使用方法如:
cita> rpc estimateQuota --to 0xb701924639d802dc8093d1a43dffa9939a4506de --data 0x13fb8817
{
"id": 1,
"jsonrpc": "2.0",
"result": "0x0000000000000000000000000000000000000000000000000000000000007fc1"
}
之前有朋友在论坛中提到 CITA 能不能有这个接口,当时我们推荐使用同一个交易的上一次执行回执中的 QuotaUsed
作为下一次交易的 Quota 的参考 。但后来又有朋友提出使 QuotaUsed 是不准确的,交易 Quota 要比 QuotaUsed 大才能使交易执行成功,而大多少是不可知的,随着合约的复杂程度不同而不同 (至于为什么,后面才会专门和大家聊)。
因此我们觉得这个估算接口还是有必要的,所以就赶紧补上了。
使用 estimateQuota 接口返回的值作为本次交易的 Quota,交易是一定能够在 CITA 系统中执行成功而不会报 Out of Quota
的。
如果大家有什么与 CITA 相关的技术话题想要我分享的,欢迎评论留言。
上一篇 : 使用 CITA 的通信加密
下一篇 : 链数据的高可用杀手