EOSIO / eos

An open source smart contract platform
https://developers.eos.io/manuals/eos
MIT License
11.27k stars 3.6k forks source link

How to fix billed CPU time is greater than the maximum billable CPU time? #8502

Closed rvit34 closed 4 years ago

rvit34 commented 4 years ago

Hi. I have reviewed two similar issues on your tracker: https://github.com/EOSIO/eos/issues/4572 https://github.com/EOSIO/eos/issues/6248

But haven't found the answer that could be helpful in my case. So I decided to create one more for clarification. Now I have an account where currently I think I have enough CPU resource to make a transaction. I've staked 20 EOS for CPU and now my available CPU is 1.29ms (1.78-0.48). See the screenshots from two public block explorers below: eos_account_resources Screenshot from 2020-01-23 00-17-55

But when I try to send a transaction I get an error: { "code": 400, "message": "Bad Request", "error": { "code": 3080004, "name": "tx_cpu_usage_exceeded", "what": "Transaction exceeded the current CPU usage limit imposed on the transaction", "details": [ { "message": "billed CPU time (362 us) is greater than the maximum billable CPU time for the transaction (13 us)", "file": "transaction_context.cpp", "line_number": 553, "method": "validate_cpu_usage_to_bill" } ] } }

This error looks quite confusing, doesn't it? As I understood the CPU time required for execute my transaction is 0.362ms but I have 1.29ms. Why is it rejected anyway?

matthewdarwin commented 4 years ago

Please check the following setting on the API node you're submitting the transaction to:

http-max-response-time-ms = 30

(default is 30)

jgiszczak commented 4 years ago

Block explorer websites are estimating what your stake might get you. Some of their estimates aren't very good. Your current stake gets you 13 microseconds, not 1.2 milliseconds. Mainnet is very busy, which has pushed transaction stake requirements much higher than previously, throwing off estimates. Try staking more CPU and see if the 13 microseconds improves.

If you're unable to stake more because you don't have enough to get a staking transaction through the network you can either use a different, better provisioned account to stake to the account you are trying to use or try to find an existing user willing to temporarily stake your account so you can add to your own stake. The staking transaction has very low CPU requirements, so try it first.

rvit34 commented 4 years ago

@jgiszczak Those two pictures from my post come from very popular eos block explorers blocks.io and eosix.io. Do you really think that their estimates so far away from truth? I don't think so.

Your current stake gets you 13 microseconds, not 1.2 milliseconds.

My current stake is 20EOS. 20 EOS is equal to 13 microseconds. Really? It's super high then, isn't? I don't think so. AFAIK the average cost for one typical transaction (eosio.token transfer) is something like 300-700 microseconds. So how much should I stake for one such transfer if 13 microseconds would cost 20EOS ? It would be sky price then.

I have found an interesting formula from this article https://medium.com/shyft-network-media/eos-resource-usage-f0a8098827d7 According to it CPU availability is calculated as: CPU Price = (CPU Staked /Total CPU Available) / 3 And it can be turned out to: Total CPU Available = CPU Staked / (CPU Price*3) According to https://www.eosrp.io current CPU price is 3.778 EOS/ms/Day Let's calculate the current CPU availability on my account: Total CPU Available = 20 / (3.778*3) = 1.764 CPU in ms This is exactly what I see now in blocks.io explorer as CPU estimation for my account.

Moreover, to check the estimation, I made a RPC call to https://api.eosnewyork.io/v1/chain/get_account from my eos client. See the response below: Screenshot from 2020-01-25 14-29-50 As you can see now I have 1.29ms available. So I think your suggestion is not correct.

rvit34 commented 4 years ago

@matthewdarwin My online wallet is connected to https://eos.greymass.com. I cannot find such setting among node info: { "server_version": "cc752d7c", "chain_id": "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906", "head_block_num": 102118265, "last_irreversible_block_num": 102117969, "last_irreversible_block_id": "06163251ecf05f16df10497489c98891991054b38e019eddadf31e31e6d5fba4", "head_block_id": "06163379d622750e1683f817ee7436d92c8f262b7adacc7f0c42b2c92b2ca3de", "head_block_time": "2020-01-27T09:18:39.500", "head_block_producer": "eosinfstones", "virtual_block_cpu_limit": 200000, "virtual_block_net_limit": 1048576000, "block_cpu_limit": 200000, "block_net_limit": 1048576, "server_version_string": "v2.0.0-rc3", "fork_db_head_block_num": 102118265, "fork_db_head_block_id": "06163379d622750e1683f817ee7436d92c8f262b7adacc7f0c42b2c92b2ca3de", "server_full_version_string": "v2.0.0-rc3-cc752d7c7996587247db7373b89f6a8c683aa9fc" }

rvit34 commented 4 years ago

Is it related to busy public node, right? Will the problem disappear if I launch my own eos node and do all transactions via its api?

jgiszczak commented 4 years ago

You're not arguing with me. You're arguing with nodeos, which has already told you the problem:

"billed CPU time (362 us) is greater than the maximum billable CPU time for the transaction (13 us)"

See that (13 us) at the end? It means 13 microseconds. That's not one of the upper limit constants or even configurable limits in the system. It's calculated on the fly and reported to you for your convenience. The node you are using is very very busy.

Running your own node is unlikely to help. It will be very busy keeping up with the network and will converge on the same CPU prices in short order.

rvit34 commented 4 years ago

@jgiszczak

I thought I could build some business logic/automation around eos transfers as I know my current limits (via get_account.cpu_limit) and can do stake/unstake when my limit goes lower than some min point. (for instance if get_account.cpu_limit.available < 1000 I stake CPU to raise my limit and continue transferring coins successfully) But get_account.cpu_limit does not mean anything, right?

So then I completely don't understand the algo behind this process. This makes usage of eos blockchain for transfers is complex and not transparent for end user. There is no guarantee that your transfer is succeeded at any point of time despite that you have enough resources. It's becoming hard to build any business logic around eos transfers as it has unpredictable behavior. Am I right?

jgiszczak commented 4 years ago

What are the results of get_account immediately after you submit a transaction which fails with the error you reported?

rvit34 commented 4 years ago

Error: { "code": 400, "message": "Bad Request", "error": { "code": 3080004, "name": "tx_cpu_usage_exceeded", "what": "Transaction exceeded the current CPU usage limit imposed on the transaction", "details": [ { "message": "billed CPU time (895 us) is greater than the maximum billable CPU time for the transaction (13 us)", "file": "transaction_context.cpp", "line_number": 553, "method": "validate_cpu_usage_to_bill" } ] } } get_account result: cpulimit.available=1300 It seems that somewhere there is some discrepancy in 100 times

jgiszczak commented 4 years ago

get_account returns essentially a cached value, the cpulimit at the time of your last successful transaction. It doesn't update again until your next successful transaction. If the traffic on the network has increased substantially in the interim, it can indeed be wrong by two orders of magnitude.

rvit34 commented 4 years ago

I've just sucessfully staked one more EOS for CPU and requested get_account info contains increased limit (1441us): { "account_name": "...", "head_block_num": 102470605, "head_block_time": "2020-01-29T15:55:47.500", "privileged": false, "last_code_update": "1970-01-01T00:00:00.000", "created": "2019-07-01T16:11:49.000", "core_liquid_balance": "23.0000 EOS", "ram_quota": 4384, "net_weight": 10500, "cpu_weight": 211500, "net_limit": { "used": 145, "available": 1051927, "max": 1052072 }, "cpu_limit": { "used": 430, "available": 1441, "max": 1871 }, "ram_usage": 3574, "permissions": [ { "perm_name": "active", "parent": "owner", "required_auth": { "threshold": 1, "keys": [ { "key": "...", "weight": 1 } ], "accounts": [], "waits": [] } }, { "perm_name": "owner", "parent": "", "required_auth": { "threshold": 1, "keys": [ { "key": "...", "weight": 1 } ], "accounts": [], "waits": [] } } ], "total_resources": { "owner": "utexiopayout", "net_weight": "1.0500 EOS", "cpu_weight": "21.1500 EOS", "ram_bytes": 2984 }, "self_delegated_bandwidth": { "from": "...", "to": "...", "net_weight": "1.0000 EOS", "cpu_weight": "21.0000 EOS" }, "refund_request": null, "voter_info": { "owner": "...", "proxy": "", "producers": [], "staked": 220000, "last_vote_weight": "0.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "flags1": 0, "reserved2": 0, "reserved3": "0 " }, "rex_info": null }

Note that the trx above has CPU cost is 429 microseconds. If I have had 13 microseconds on my account It would have been rejected as well as transaction from 1st post.

rvit34 commented 4 years ago

The error I reported from first post is unstake CPU operation. Maybe this is a reason of the issue. When do I unstake CPU my cpu limit goes down or not?

GeoffrayMoinsLeQuart commented 4 years ago

Hello,

I am trying to send eos from eos voter to binance. I don't understand exactly whats happening. Here is the error message of my tx :

Error billed CPU time (231 us) is greater than the maximum billable CPU time for the transaction (92 us)

{ "code":400 "message":"Bad Request" "error":{ "code":3080004 "name":"tx_cpu_usage_exceeded" "what":"Transaction exceeded the current CPU usage limit imposed on the transaction" "details":[ 0:{ "message":"billed CPU time (231 us) is greater than the maximum billable CPU time for the transaction (92 us)" "file":"transaction_context.cpp" "line_number":553 "method":"validate_cpu_usage_to_bill" } ] } }

Those are my attributes : Liquid 85.2214 EOS Staked to Self 2.0000 EOS Staked to Others 0.0000 EOS Total 87.2214 EOS RAM Amount 9.55 kB

Has anyone an idea ? :)

Have a good one !

taokayan commented 4 years ago

@GeoffrayMoinsLeQuart you just need to stake more for CPU. maybe 10-20 EOS

wangke0809 commented 4 years ago

When pushing a transaction to the RPC node, the used time of transaction is calculated by this RPC node, which is related to the CPU status of the RPC node. Eventually, the on-chain transaction time is calculated by the packaging node (producer), so although you may have a lot of CPU time, you cannot push a transaction. This defect is inherent in current EOS node designs. You can choose a faster node to push transactions, or stake more EOS for the CPU time. More details can be found here: https://blog.csdn.net/wangke0809/article/details/104138651 (in Chinese)

cppfuns commented 4 years ago

I currently build a private chain, EOS 1.8 version, TPS average is 20. The transaction volume is not much, and the account with the same error has a lot of CPU resources left. Are there any related settings to adjust for this kind of error?

eosunstake commented 4 years ago

I am having this same issue, but I am trying to unstake all of my tokens. I am using the EOS Voter wallet as well. Any solutions?

cppfuns commented 4 years ago

image image image

Our private chain has not had much transaction volume, but why does the CPU fluctuate so much? It is easy to report errors during peak periods. All node servers have the same CPU model 8 vCPU 32 GiB (I / O optimization) ecs.g6.2xlarge

cppfuns commented 4 years ago

And it is found that when the CPU usage of each BP server in the chain network is high, the CPU usage of the synchronization node is also high. When the CPU of each BP server of the chain network returns to normal, the CPU usage of the synchronization node also recovers. image

image

rvit34 commented 4 years ago

I am having this same issue, but I am trying to unstake all of my tokens. I am using the EOS Voter wallet as well. Any solutions?

Link your wallet with https://bloks.io/ There you can send up to 5 transactions per day with free CPU. Use them for stake/unstake CPU operations only.

gituser commented 3 years ago

When pushing a transaction to the RPC node, the used time of transaction is calculated by this RPC node, which is related to the CPU status of the RPC node. Eventually, the on-chain transaction time is calculated by the packaging node (producer), so although you may have a lot of CPU time, you cannot push a transaction. This defect is inherent in current EOS node designs. You can choose a faster node to push transactions, or stake more EOS for the CPU time. More details can be found here: https://blog.csdn.net/wangke0809/article/details/104138651 (in Chinese)

I'm constantly getting this error 'CPU time is greater than the maximum billable CPU time' when I try to push the transaction on EOS blockchain.

I do:

Why this issue has been closed as it's clearly a bug?