欢迎所有爱好区块链技术的人加入。

ARCHIVES / 895.HTML

Transaction exceeded the current CPU usage limit imposed on the transaction

Surou EOS-新手问答

最近链发送交易过大时容易发生一下错误

{
	"message": "Internal Service Error",
	"code": "500",
	"error": {
		"code": "3080004",
		"name": "tx_cpu_usage_exceeded",
		"what": "Transaction exceeded the current CPU usage limit imposed on the transaction",
		"details": [{
			"message": "transaction was executing for too long",
			"file": "transaction_context.cpp",
			"line_number": 488,
			"method": "checktime"
		}, {
			"message": "pending console output: ",
			"file": "apply_context.cpp",
			"line_number": 113,
			"method": "exec_one"
		}]
	}
}

根据错误信息,定位源代码位置 (github)

由于now > _deadline并且 deadline_exception_code == tx_cpu_usage_exceeded::code_value 走到此断言逻辑
倒推到函数调用位置(github)

checktime(); // Fail early if deadline has already been exceeded

提示信息为:如果已超过截止日期,则提早失败
继续反推代码
由于(github)交易组装时trx.max_cpu_usage_ms固定设置的0。所以,判断逻辑出自(github)

// Possibly lower objective_duration_limit to the maximum cpu usage a transaction is allowed to be billed
if( cfg.max_transaction_cpu_usage <= objective_duration_limit.count() ) {
	objective_duration_limit = fc::microseconds(cfg.max_transaction_cpu_usage);
	billing_timer_exception_code = tx_cpu_usage_exceeded::code_value;
	_deadline = start + objective_duration_limit;
}
auto& rl = control.get_mutable_resource_limits_manager();
objective_duration_limit = fc::microseconds( rl.get_block_cpu_limit() );
_deadline = start + objective_duration_limit;
if(now > _deadline) {
	// 报异常
}

get_mutable_resource_limits_manager(github)

resource_limits_manager&         controller::get_mutable_resource_limits_manager()
{
   return my->resource_limits;
}

get_block_cpu_limit(github)

uint64_t resource_limits_manager::get_block_cpu_limit() const {
   const auto& state = _db.get<resource_limits_state_object>();
   const auto& config = _db.get<resource_limits_config_object>();
   return config.cpu_limit_parameters.max - state.pending_cpu_usage;
}

跟进停止

发现是由于合约中使用了std::vector<std::string> 持续存储大量数据,导致单次CPU运算执行耗时持续增长。

结论

当合约中Table单条记录中,如果使用vector不要存储过多数据,以及数据结构过于复杂的struct。
如有对应需求,可以拆分子表,然后使用子表记录id索引对应。