-
Notifications
You must be signed in to change notification settings - Fork 869
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(evm): fixed the problem gas_used is 0 when using evm type tx to transfer token to module account #1801
Conversation
…ransfer token to module account
Codecov Report
@@ Coverage Diff @@
## main #1801 +/- ##
==========================================
- Coverage 70.07% 69.93% -0.14%
==========================================
Files 324 327 +3
Lines 24017 24166 +149
==========================================
+ Hits 16829 16901 +72
- Misses 6327 6401 +74
- Partials 861 864 +3
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution @luchenqun!!
Left a couple of comments
Please resolve conflicts
Also, would be great to add tests for this, e.g: we could add something like this in the
|
Sorry, I'm not very proficient in Python (still learning). Please help me complete the relevant tests. |
No worries about the test, I can add it later |
…OrExpectedFailure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix lint. Besides that things look good to me. Thanks for the contribution!
We will not merge this PR yet because we have a release coming soon so we want to keep main clean but we will merge it afterwards once we have the according tests.
I won’t take the blame for this. It was @GAtom22 who helped me update the comments and forgot to execute |
When we transfer token to a module account, such as the distribution module account evmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8974jnh (ethereum-style account is 0x93354845030274cD4bf1686Abd60AB28EC52e1a7), two scenarios can occur:
The transaction receipt example below is obtained when using the cosmos type to send the transaction. The gas_used value is displayed as 70711, the gas_used value is correct.
When send the transaction using the evm type. The following is an example of a queried transaction receipt, in which gas_used is displayed as 0. Because when a evm transaction fails, all gas will be deducted, so the gas_used data here is incorrect (Note: Please make sure value is not 0, otherwise this error will not be triggered.).
At the same time, after the transaction is executed, we can query the transaction receipt through eth_getTransactionReceipt by transaction hash, but we cannot obtain the transaction receipt.
If we only solve this problem, we can prohibit transfers to the module account during the checking phase of the transaction. But considering the general situation, such as the smart contract below, the user can pass in the module account as a parameter, then we cannot detect it.。
So we must have a general method to solve such problems.
The reason why gas_used=0 occurs is because when executing the transaction in the EVM module, an error is triggered during the
stateDB.Commit()
operation in theApplyMessageWithConfig
function. As a result, theApplyTransaction
function returns an error prematurely without executingk.ResetGasMeterAndConsumeGas(ctx, totalGasUsed)
, leading to incorrect gas_used value. In general, whenever an error occurs in theApplyMessageWithConfig
function, there can be a gas_used=0 issue. I only used the example of an error instateDB.Commit()
to illustrate this problem.So, in order to solve this problem, when the
ApplyMessageWithConfig
function encounters an error, we should call thek.ResetGasMeterAndConsumeGas(ctx, txGasLimit)
function before returning the error. Here is the modified code for theApplyTransaction
function:Attention: The parameter for ResetGasMeterAndConsumeGas must be the gas limit of the transaction, which is
ctx.GasMeter().Limit()
, instead of the gas limit of the current message, which ismsg.Gas()
. This is because if a transaction may contains multiple messages, if one of the messages fails, all messages will fail and all gas will be deducted.However, there is currently no interface for including multiple messages within a single transaction. Below are some notes on how to construct multiple messages within a single transaction for reference:
First, sign a transaction using ethers.js. The code is as follows:
Then, the signed message is assembled into a cosmos type transaction. I write a function
BuildTx
in rpc/backend/call_tx.go to complete this function, and then call the function in GasPrice. The relevant code is as follows:Finally, call Ethereum's rpc interface eth_gasPrice to trigger the assembly of the transaction. Then you can get a cosmos transaction containing multiple messages in the log, and send this transaction to the chain through
http://127.0.0.1:26657/broadcast_tx_commit.
In order to facilitate testing, you can transfer 10evmos to the address 0x73F725bb91632Ca76cf3aaA79dcFB6dece9A7c78, and you can use the transaction I have assembled below for testing.
0x0aad070aa5020a1f2f65746865726d696e742e65766d2e76312e4d7367457468657265756d54781281020aba010a1a2f65746865726d696e742e65766d2e76312e4c65676163795478129b01120b35303030303030303030301880b48913222a3078393333353438343530333032373463443462663136383641626436304142323845433532653161372a13313030303030303030303030303030303030303a02467442209787e82add28eeced04ac1cd7b1fe1ddfd1b40eb44b12794f2e07c59e8a6d1734a2037e51635be25cc59d2acd7730c59cdd11b8d7583e2ac341b9df2ef3d822c7e7e1a423078396237623234396463353435313337613663383534633831306131383334316562306237373338313831623433653135636236376435653733343862613534370aa7020a1f2f65746865726d696e742e65766d2e76312e4d7367457468657265756d54781283020abc010a1a2f65746865726d696e742e65766d2e76312e4c65676163795478129d010801120b35303030303030303030301880b48913222a3078303030303042653638313966343134303032323537303244333264336464323336363344643639302a13313030303030303030303030303030303030303a02467342201e1122036c63185fab473e379b998bfd28e0e94585e77be5f935fcaf6e240d674a206dc49def72dd513e23d473bd6f86dcd49712766715af2da0a11fb923da686b241a423078646463376138393134333064346130396434646430303135393336353732363932643663613537313933323362646465663235316461656264623766373965330aa7020a1f2f65746865726d696e742e65766d2e76312e4d7367457468657265756d54781283020abc010a1a2f65746865726d696e742e65766d2e76312e4c65676163795478129d010802120b35303030303030303030301880b48913222a3078313131313130324464333231363042303634463241353132434445663734624664423661394639362a13313030303030303030303030303030303030303a0246744220cd92e971a98cea933c35545226ac55c9fca3cdbf26d98422efd27ef48dfce93b4a207f7e8fae91998f0a6fe6b55e375a4dd15d20c14dcee5b0e99af48ffd011405c91a42307834613233393037373931343636663666396239363730363534636530633339393637626664396438343461353830633533373439393637616432613463393163fa3f2e0a2c2f65746865726d696e742e65766d2e76312e457874656e73696f6e4f7074696f6e73457468657265756d5478122612240a1d0a066165766d6f7312133630303030303030303030303030303030303010809c9c39
As for the other question, if the receipt cannot be found when querying by transaction hash, it is because the returned data does not consider this special case. Add the corresponding handling logic to fix it. The relevant code is as follows: