-
Notifications
You must be signed in to change notification settings - Fork 335
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 eth call gas estimation discrepancy #2440
Conversation
Coverage generated "Thu Aug 24 18:06:40 UTC 2023": Master coverage: 87.39% |
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.
Some small comments regarding code cleanup mostly. LGTM.
// const { result } = await context.createBlock( | ||
// await createTransaction(context, { | ||
// ...CHARLETH_TRANSACTION_TEMPLATE, | ||
// to: ADDRESS_ERC20, | ||
// data: ERC20_INTERFACE.encodeFunctionData("approve", [alith.address, 100000000]), | ||
// }) | ||
// ); | ||
|
||
// const receipt = await context.web3.eth.getTransactionReceipt(result.hash); | ||
// console.log("Zero approve gas used", receipt.gasUsed); | ||
// expect(receipt.status).to.equal(true); |
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.
// const { result } = await context.createBlock( | |
// await createTransaction(context, { | |
// ...CHARLETH_TRANSACTION_TEMPLATE, | |
// to: ADDRESS_ERC20, | |
// data: ERC20_INTERFACE.encodeFunctionData("approve", [alith.address, 100000000]), | |
// }) | |
// ); | |
// const receipt = await context.web3.eth.getTransactionReceipt(result.hash); | |
// console.log("Zero approve gas used", receipt.gasUsed); | |
// expect(receipt.status).to.equal(true); |
let gasEst = await context.web3.eth.estimateGas({ | ||
from: alith.address, | ||
data: ERC20_INTERFACE.encodeFunctionData("approve", [baltathar.address, 0]), | ||
// gasPrice: "0x0", |
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.
// gasPrice: "0x0", |
import { KeyringPair } from "@polkadot/keyring/types"; | ||
import { ParaId } from "@polkadot/types/interfaces"; |
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.
Seems that these imports are not used
import { KeyringPair } from "@polkadot/keyring/types"; | |
import { ParaId } from "@polkadot/types/interfaces"; |
|
||
import { KeyringPair } from "@polkadot/keyring/types"; | ||
import { ParaId } from "@polkadot/types/interfaces"; | ||
import { BN, hexToU8a, numberToHex, stringToHex, u8aToHex } from "@polkadot/util"; |
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.
import { BN, hexToU8a, numberToHex, stringToHex, u8aToHex } from "@polkadot/util"; | |
import { BN, hexToU8a, u8aToHex } from "@polkadot/util"; |
import { blake2AsU8a, xxhashAsU8a } from "@polkadot/util-crypto"; | ||
import { expect } from "chai"; | ||
|
||
import { ALITH_ADDRESS, alith, baltathar, generateKeyringPair } from "../../util/accounts"; |
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.
import { ALITH_ADDRESS, alith, baltathar, generateKeyringPair } from "../../util/accounts"; | |
import { ALITH_ADDRESS, alith, baltathar } from "../../util/accounts"; |
import { expect } from "chai"; | ||
|
||
import { ALITH_ADDRESS, alith, baltathar, generateKeyringPair } from "../../util/accounts"; | ||
import { PARA_2000_SOURCE_LOCATION, RELAY_SOURCE_LOCATION } from "../../util/assets"; |
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.
import { PARA_2000_SOURCE_LOCATION, RELAY_SOURCE_LOCATION } from "../../util/assets"; | |
import { RELAY_SOURCE_LOCATION } from "../../util/assets"; |
import { | ||
registerForeignAsset, | ||
injectHrmpMessageAndSeal, | ||
RawXcmMessage, | ||
XcmFragment, | ||
weightMessage, | ||
} from "../../util/xcm"; |
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.
import { | |
registerForeignAsset, | |
injectHrmpMessageAndSeal, | |
RawXcmMessage, | |
XcmFragment, | |
weightMessage, | |
} from "../../util/xcm"; | |
import { registerForeignAsset } from "../../util/xcm"; |
XcmFragment, | ||
weightMessage, | ||
} from "../../util/xcm"; | ||
import { customWeb3Request, web3EthCall } from "../../util/providers"; |
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.
import { customWeb3Request, web3EthCall } from "../../util/providers"; |
|
||
import { describeDevMoonbeam } from "../../util/setup-dev-tests"; | ||
|
||
import { expectOk } from "../../util/expect"; |
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.
import { expectOk } from "../../util/expect"; |
); | ||
|
||
const receipt = await context.web3.eth.getTransactionReceipt(result.hash); | ||
console.log("First approve gas used", receipt.gasUsed); |
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.
Shouldn't we avoid console.logging inside TS tests? I think we had console.log()
related issues in our CI in the past (correct me if I'm wrong).
console.log("First approve gas used", receipt.gasUsed); |
to: ADDRESS_ERC20, | ||
}); | ||
|
||
console.log("Revoke gas estimate", gasEst); |
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.
Same case here
console.log("Revoke gas estimate", gasEst); |
); | ||
|
||
const receipt2 = await context.web3.eth.getTransactionReceipt(result2.hash); | ||
console.log("Revoke gas used", receipt2.gasUsed); |
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.
console.log("Revoke gas used", receipt2.gasUsed); |
runtime/common/src/apis.rs
Outdated
// 65 bytes signature | ||
210; | ||
255; |
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.
How did we get 210 -> 255
? If it's 2 * 32
from max_fee_per_gas
and max_prority_fee_per_gas
, shouldn't it be 274
?
The numbers from the comments do add up correctly to 255
at least...
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.
Also, it seems like we lost from
. Is this because there is no such thing in an actual transaction (it's recovered from its signature)...?
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.
from is 20, so 210 + 64 - 20 => 254
, still off by one 😆
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.
it seems like we lost from. Is this because there is no such thing in an actual transaction
Yes exactly
still off by one
The one come from access_list, even if the access list is empty, the scale encoded format take 1 byte for the empty Vec.
* fix tx encoded size estimation * Working test * test cleanup * test cleanup 2 * accont for pallet index + call index+ transaction type enum variant * pretiier --------- Co-authored-by: Francisco Gamundi <francisco@moonsonglabs.com>
What does it do?
Fix a discrepancy bug between eth_call and on-chain tx execution.
The bug is caused by the fact that the PoV consumed by the ethereum transaction is counted differently in the estimation context than in the on-chain context.
The discrepancy is due to the fact that estimation queries generally not provide values for fields
max_fee_per_gas
andmax_priority_fee_per_gas
whereas the on-chain transaction provides values for these fields.The solution is to consider that these fields are always supplied to estimate the size of the on-chain transaction, this implies over-estimation of 45 gas (negligible for fees) only for legacy transactions and only if the "pov gas" is greater than the used gas.
What important points reviewers should know?
Is there something left for follow-up PRs?
What alternative implementations were considered?
Are there relevant PRs or issues in other repositories (Substrate, Polkadot, Frontier, Cumulus)?
What value does it bring to the blockchain users?