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

fix(fvm): fix (and prevent) two bugs in out of gas handling. #1830

Merged
merged 1 commit into from
Aug 18, 2023

Conversation

Stebalien
Copy link
Member

My last commit introduced a bug where I ignored the error from a call to CallManager::charge_gas when we meant to simply ignore the gas timer, not the entire error. This bug was in the charge for on_method_return.

So I decided to remove the must_use marker from gas timers in general so we didn't have to explicitly ignore the results. We generally don't care about these timers anyways.

While doing that, I found another bug in the tipset_cid syscall where we made the same mistake. this issue is tricker because this code is already deployed to mainnet, but we should be able to fix it without any consensus issues. Basically, right now:

  1. We won't detect the out of gas condition when we should.
  2. We'll fetch the requested tipset CID from state.
  3. We'll return it to the user.
  4. The actor (the EVM) will try to charge a bit of gas when handling the return value from the syscall.
  5. The actor will run out of gas and abort with an OutOfGas.

Now, we'll just abort with an OutOfGas error immediately.

@Stebalien Stebalien requested a review from arajasek August 2, 2023 20:53
@Stebalien
Copy link
Member Author

Syncing mainnet just to double check.

@Stebalien
Copy link
Member Author

Ok, the network is syncing just fine.

@arajasek
Copy link
Contributor

arajasek commented Aug 4, 2023

So I think you're right that the tipset_cid change will behave exactly the same way, i'm just not SURE. Syncing mainnet seems like a weak test -- you're only gonna notice this if we actually have a message that invokes a contract that runs out of gas as it's querying a tipset_cid, right?

We probably want to test this out more if we strongly care. The question is -- do we? We expect FVM master to break compatibility with mainnet soon anyway, right (as we prep for nv21). Can we just say now is that point? Or stage this in some next branch for now?

@Stebalien
Copy link
Member Author

I'm trying to keep the breaking changes out of master this time till the FIPs start landing, if at all possible. I guess this is a bug fix so not a FIP-able change?

I'm going to just test this manually by explicitly setting the gas to zero in this method to make sure that these two cases are indistinguishable.

My last commit introduced a bug where I ignored the error from a call to
`CallManager::charge_gas` when we _meant_ to simply ignore the gas
timer, not the entire error. This bug was in the charge for
`on_method_return`.

So I decided to remove the `must_use` marker from gas timers _in
general_ so we didn't have to explicitly ignore the results. We
generally don't care about these timers anyways.

While doing that, I found another bug in the `tipset_cid` syscall where
we made the same mistake. this issue is tricker because this code is
already deployed to mainnet, but we should be able to fix it without any
consensus issues. Basically, right now:

1. We won't detect the out of gas condition when we should.
2. We'll fetch the requested tipset CID from state.
3. We'll return it to the user.
4. The actor (the EVM) will try to charge a bit of gas when handling the
return value from the syscall.
5. The actor will run out of gas and abort with an OutOfGas.

Now, we'll just abort with an OutOfGas error immediately.
@Stebalien
Copy link
Member Author

Ok, I've validated that the two cases are indistinguishable due to the SDK. I.e., we'll always run out of gas immediately anyways, even if we don't return an explicit out of gas error.

@Stebalien Stebalien enabled auto-merge (squash) August 18, 2023 19:16
@Stebalien Stebalien merged commit 6447038 into master Aug 18, 2023
14 checks passed
@Stebalien Stebalien deleted the steb/fix-gas-early-return branch August 18, 2023 19:30
Stebalien added a commit that referenced this pull request Aug 18, 2023
My last commit introduced a bug where I ignored the error from a call to
`CallManager::charge_gas` when we _meant_ to simply ignore the gas
timer, not the entire error. This bug was in the charge for
`on_method_return`.

So I decided to remove the `must_use` marker from gas timers _in
general_ so we didn't have to explicitly ignore the results. We
generally don't care about these timers anyways.

While doing that, I found another bug in the `tipset_cid` syscall where
we made the same mistake. this issue is tricker because this code is
already deployed to mainnet, but we should be able to fix it without any
consensus issues. Basically, right now:

1. We won't detect the out of gas condition when we should.
2. We'll fetch the requested tipset CID from state.
3. We'll return it to the user.
4. The actor (the EVM) will try to charge a bit of gas when handling the
return value from the syscall.
5. The actor will run out of gas and abort with an OutOfGas.

Now, we'll just abort with an OutOfGas error immediately.
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