Skip to content
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

AA-543: Refactor post execution #552

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open

Conversation

drortirosh
Copy link
Contributor

No description provided.

@forshtat forshtat changed the title Refactor post execution AA-543: Refactor post execution Feb 27, 2025
@drortirosh drortirosh force-pushed the refactor-post-execution branch from d261501 to 19be0d2 Compare February 27, 2025 11:18
@drortirosh drortirosh force-pushed the refactor-post-execution branch from a65d294 to 5075d38 Compare February 27, 2025 17:03
}
bool callSuccess;
if (success) {
callSuccess = returnData != 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest executionSuccess or something like that, more explicit.

emitUserOperationEvent(opInfo, false, actualGasCost, actualGas);
collected = actualGasCost;
// innerCall reverted on prefund too low.
// below we re-calculate the cast cost and refund.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where? Put function name, lines or some other meaningful reference to what you mean here.

Also, this entire if is empty, could we maybe "invert" it to be else if (!innerRevertCode == INNER_REVERT_LOW_PREFUND) { ... } ??

Comment on lines 157 to 160
* call after innerCall executed to call the account's callData and paymaster's postOp.
* - calculate the overall gas used and unuased penalty.
* - refund payer if needed
* - emit UserOperationEvent
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrite this comment. Use ChatGPT.

unchecked {
uint256 prefund = opInfo.prefund;
uint256 actualGasCost = actualGas * getUserOpGasPrice(opInfo.mUserOp);
uint256 refund;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you seriously creating two variables - refund and prefund here? Absolutely not. These two variables MUST have two or three words names that don't sound anything alike.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest better names.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, originalPrefund and remainingGasRefund?
@shahafn could you help me out here? 😄

refund = prefund - actualGasCost;
} else {
actualGasCost = prefund;
//depending where the over-gas-used was found, we either reverted innerCall or not.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of writing this comment add a boolean parameter to the emitPrefundTooLow - we don't always need it but it will help make the code flow more clear.

Comment on lines +384 to +388
uint256 gasUsed = preGas - gasleft();
assembly ("memory-safe") {
mstore(0, INNER_OUT_OF_GAS)
revert(0, 32)
mstore(32, gasUsed)
revert(0, 64)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are making a big refactoring now, would you consider extracting this entire unchecked { ... } block to some _verifyEnoughGasForInner function? This is a very distracting code.

uint256 postOpGasUsed = postOpPreGas - gasleft();
postOpUnusedGasPenalty = _getUnusedGasPenalty(postOpGasUsed, mUserOp.paymasterPostOpGasLimit);
actualGas = executionGas + _getUnusedGasPenalty(executionGas, mUserOp.callGasLimit) + opInfo.preOpGas;
if (context.length > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for the entire if (context.length > 0) { ... } block - it would probably cost nothing to make it an internal function.

if (context.length > 0) {
uint256 postOpPreGas = gasleft();
uint256 actualGasCostForPostOp = actualGas * gasPrice;
uint256 paymasterPostOpGasLimit = mUserOp.paymasterPostOpGasLimit;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a variable if mUserOp is in memory anyways? MLOAD costs 3 gas, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.
mUserOp is "double-reference", and in the past, it was better to copy a struct member to a local (stack) one.
but apparently, the compiler now behaves better if we don't.
(btw: its not good optimization of the compiler: it should be agnostic to the way we read again the same memory var)

uint256 postOpPreGas = gasleft();
uint256 actualGasCostForPostOp = actualGas * gasPrice;
uint256 paymasterPostOpGasLimit = mUserOp.paymasterPostOpGasLimit;
// todo: no real need to check if paymaster has code. we already called validatePaymasdterUserOp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now is not a time to add new TODOs. Either go full assembly (not recommened) or ignore the unnecessary "has code" checks you get from solidity (recommended).

// todo: no real need to check if paymaster has code. we already called validatePaymasdterUserOp
try IPaymaster(paymaster).postOp{
gas: paymasterPostOpGasLimit
}(mode, context, actualGasCostForPostOp, gasPrice)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can totally remove the postOpReverted "mode" from the codebase by the way.

@forshtat
Copy link
Collaborator

forshtat commented Mar 3, 2025

A remider to self to remove postOpReverted from ERC-4337 if this PR is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants