-
Notifications
You must be signed in to change notification settings - Fork 179
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
[Flow EVM] prepare the StateDB and the Emulator to support batch run operations #5577
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5577 +/- ##
==========================================
- Coverage 55.67% 55.65% -0.02%
==========================================
Files 1037 1037
Lines 101404 101377 -27
==========================================
- Hits 56457 56423 -34
- Misses 40607 40615 +8
+ Partials 4340 4339 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
// if is a EVM validation error first unwrap one level | ||
if IsEVMValidationError(err) { | ||
// check local errors | ||
switch err { | ||
case ErrInvalidBalance: | ||
return ValidationErrCodeInvalidBalance | ||
case ErrInsufficientComputation: | ||
return ValidationErrCodeInsufficientComputation | ||
case ErrUnAuthroizedMethodCall: | ||
return ValidationErrCodeUnAuthroizedMethodCall | ||
case ErrWithdrawBalanceRounding: | ||
return ValidationErrCodeWithdrawBalanceRounding | ||
} | ||
err = errors.Unwrap(err) | ||
} | ||
|
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.
These are not part of validation errors anymore, these all requires the flow transaction to revert
// invalid balance is provided (e.g. negative value) | ||
ValidationErrCodeInvalidBalance ErrorCode = 101 | ||
// insufficient computation is left in the flow transaction | ||
ValidationErrCodeInsufficientComputation ErrorCode = 102 | ||
// unauthroized method call | ||
ValidationErrCodeUnAuthroizedMethodCall ErrorCode = 103 | ||
// withdraw balance is prone to rounding error | ||
ValidationErrCodeWithdrawBalanceRounding ErrorCode = 104 |
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.
Not part of the validation errors and the codes are not used.
fvm/evm/emulator/emulator.go
Outdated
@@ -244,10 +268,15 @@ func (proc *procedure) withdrawFrom( | |||
return res, err | |||
} | |||
|
|||
// if any error (invalid or vm) on the internal call, revert and don't commit any change | |||
if res.Invalid() || res.Failed() { | |||
return res, types.ErrInternalDirecCallFailed |
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.
is it intentional to swallow the exact error? should we wrap it?
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 was intentional to stop the flow transaction, but now I think we might be able to send the result upward and do everything on the handler.
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.
I did more looking in it, the reason I think it might be a better option to make an intentional error for now is the direct call is also invisible to the user (we form it). we might revisit this in the future.
// Any error returned by any of the methods (e.g. stateDB errors) if non-fatal stops the outer flow transaction | ||
// if fatal stops the node. | ||
// EVM validation errors and EVM execution errors are part of the returned result | ||
// and should be handled separately. |
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.
much better design ❤️
@@ -49,6 +56,9 @@ func (res *Result) VMErrorString() string { | |||
// and for each log, Address, Topics, Data (consensus fields) | |||
// During execution we also do fill in BlockNumber, TxIndex, Index (event index) | |||
func (res *Result) Receipt() *gethTypes.Receipt { | |||
if res.Invalid() { |
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.
I wonder if not having a receipt for invalid transactions is correct since they do consume gas?
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.
Thats an EVM-expected behaviour that we can't change easily. For example, in the case of a nonce mismatch (ahead of state), there should never be a state change or receipt otherwise the 3rd party apps will break after resubmission of the transaction when the nonce becomes the right number.
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.
Nice!
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.
LGTM 🚀
// given we charge the fees on flow transaction and we | ||
// are doing on chain validation we can/should charge the | ||
// user for the validation fee. | ||
const InvalidTransactionGasCost = 1_000 |
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.
This is an ok solution, but I think it might be better if we introduce a new computationKind for failed transactions that can then be dynamically calibrated.
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.
Good idea, I'll add an issue for it.
This PR
is part 1 of the changes needed for [Flow EVM] supporting evm.
batchRun
#5501changes the stateDB
Reset
method to clean up the transient part of the storage (logs, transient slots, ... ), this method can be used between transactions.Finalize
part of theCommit
method and add it as a separate method. Finalize, commit the changes from the Atree cache into the final ledger state. This has been added so when executing multiple transactions, we can save time on the serialization time of Atree.updates the way we return errors from the emulator and handle them on the handler
RunTransaction
.Given that ValidationErrors are explicitly captured now, we don't need a wrapper.